Jump to content

Pat Foley

Members
  • Content Count

    428
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by Pat Foley


  1. Try setting the TabStop property of Radiogroup to True when none of the controls are selected. In the RadioGroups.OnEnter set focus on a control so keys can change the selection as needed.

     

    //Need RG .TabStop prop set to True to 'focus' the groupbox when its control index
    //is -1;
    procedure TformInstructorStation.RadioGroup2Enter(Sender: TObject);
    begin
      with Sender as TRadioGroup do
        if ItemIndex = -1 then
          TRadioButton(Controls[0]).SetFocus;
    
     //(Sender as TRadioGroup).OnEnter := nil;
    end;

     


  2. How about a collection of check boxes  TCheckListBox 

     

    The sample simply clears the checkboxes that were in the IDE and adds the ones that are in Array<string>

     

    To extend you would change the Panel and Tstrings that the UI uses update the backend. Here the back end simply updates the UI when programs are used.

     

    It uses a Ddd pattern Data driven pattern.  " Update the data early and often"   

     

    
    class function TptrApps.HookInUI(inSG: TStringGrid; inLog: TStrings; inChBxs: TcheckListBox;
         inBanner: TPanel): TptrApps;
    begin
      Result := nil;
      focusedApp := @cacheApp;
      var R := TptrApps.Create;
    
      R.ChBxs := inChBxs;
      R.ChBxs.OnClick := R.changeExesList;
      R.ChBxs.Items.Clear;
      for var I := Low(goodApps) to High(goodApps) do
        begin
          R.ChBxs.Items.add(goodApps[I]);
          R.ChBxs.Checked[I] := True;
          ...
    
    const
      selfClass = 'FrmPat';
    
      GoodApps: Tarray<string> = [cEveryThing,'Shell_TrayWnd','Notepad', 'TAppBuilder', 'Window',
       'Chrome_WidgetWin_1', 'Notepad++', selfClass, 'TfmPeInformation' ];
          
    

     

     

    • Like 1

  3. Outlook's contact info is a vcard file and calendar event is vcalendar *.vcs or *.ics file. The employee calendar shows the events provided by the calendars the employee has access to. 


    Example of email attachment
    https://answers.microsoft.com/en-us/outlook_com/forum/all/how-to-insert-attachment-to-recurring-meeting 

    You would simply add an event attachment to the email of employee.

     

    But better to educate the office staff how to use Outlook calendar by having the secretary set the events on the employee calendars as needed. 

    Employee leave requests are sent to office manager. If approved the secretary amends the department's calendar which updates the employee calendar.

    The employee looks at the calendar events provided by the secretary. The secretary knows when the employee knows of a calendar event by the employee opening an email with a calendar event attachment and confirming the event.

      
     


  4. Here's my 7 cents worth.  'Explicitly' use a's Value to remove need for braces.

    var
      a: TplFilterValue<Boolean>;
      B: Boolean;
      procedure  //Boolean User output
        Bout (argS: string; aB: Boolean);
          begin
            writeln(argS + ' = ', aB);
          end;
      function
        NotFixup(aB: TplFilterValue<Boolean>): Boolean;
          begin
            Result := not aB.Value;
          end;
    
    begin
      try
        a.Value := True;
        //if not a then
          Bout('not a', not a);
          Bout('a or True', a or True);
          Bout('a and True', a and True);
    
        Writeln('  NotFixup');
        //if not a or True then  // <<--- Error [dcc32 Error] E2015 Operator not applicable to this operand type
          Bout('Notfixup(a) or True', NotFixup(a) or True);
          Bout('NotFixup(a or True)', NotFixup(a or True));
    
        Writeln('  Precedence manual sort fix');
         // Bout('True or not (a)', True or not (a));
          Bout('True or not a', True or not a);
    
        Writeln('  not precedence working for boolean here');
          B := a;
          Bout('not B or True', not B or True);
          a := not B or True;
        Writeln('  Or use a''''s Value explicitly :)');
    
          Bout('not a.value or True', not a.value or True);
    
        readln;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.

     


  5. 4 hours ago, pmcgee said:

    Currently Delphi doesn't really qualify as a good teaching language any more - which I think is really sad.

    Without some more modern language facilities, it would be unfair to modern (say university level) students, and I'd like to see that change. 

    // Define a record type as a data class
    data class cpRecord(
        var UI: TStringGrid, // Assuming this is a custom type
        var compute: TProc, // Assuming this is a functional type
        var Value: PDouble // Assuming this is a pointer type
    )
    
    // Define a custom generic list as a subclass of MutableList
    class TcustomList : MutableList<cpRecord> {
        // Delegate the implementation to an ArrayList
        private val list = ArrayList<cpRecord>()
    
        // Implement the abstract methods of MutableList
        override val size: Int
            get() = list.size
    ...

    I think "port"able coding should be what is taught. Starting with Excel.

     

    Above code from a "Bing" prompt porting a Delphi TList<PRecord> to Kotlin.  The "Precords" allow more shallow code on D jobs and should allow a port on the Android side.

     

    In the past one could simply use JS.evaluate(some script).

         

     

     


  6. Here is a sample using a ColorDialog and ListBox.  Note In the IDE you can interact with the colordialog on the form to preload custom colors. The ColorDialog can be to show full with in object inspector.

    procedure TForm1.Button1Click(Sender: TObject);
    begin
     If ColorDialog1.Execute Then
     Listbox1.Items := ColorDialog1.CustomColors;
    end;
    
    procedure TForm1.ListBox1Click(Sender: TObject);
    begin
      if Sender is TListBox then
        begin
          var lb := TListBox(Sender);
          var I  := lb.ItemIndex;
    
          Color := StrtoInt('$'
                             + lb
                                .Items
                                .ValueFromIndex[I]
                           );
        end;
    end;

     


  7. 5 hours ago, Lars Fosdal said:

    Something that is often overlooked is to limit the redraw frequency. If you redraw the display on every update and there are many updates per second, you may save a lot of time on triggering the invalidate at a capped rate, i.e. not do a full redraw every time, but update once every fixed time interval.  Unless you are doing video processing - a redraw at maximum twice per second should be more than sufficient?

    But overclocking is fun!

    Using paint; override; with say TShape a tGraphicalControl allows using inherited to draw existing shape and add text as needed. Not using inherited means drawing your own polygon. The sample simply draws over the TShape control Ok But the focus rect yielded some relics.

    In the past it was necessary to exit a timer event when busy or in debug mode. Even with example switches the following stacks up clicks events. I put a call to Button8click in the formPaint and it ran but slowly. 

     

    Otherwise just invalidate the controls as needed. 

    var Button8clickIsBusy: Integer = 0;
    var OneShot: Boolean = False;
    
    procedure TForm1.Button8Click(Sender: TObject);
    const
      Red = clRed;
      Green = clGreen;
      Colors: Array of Tcolor = [clGreen,clRed,clBlue,clYellow];
    
    var
      sw: TStopwatch;
      sX: string;
    
             function RandomFontColor: Tcolor;
             begin
               var Clr := High(Colors);
               var R := Random(Clr);
               Result := Colors[R];
             end;
    
    begin
      sw.Reset;
      sw.Start;
      If Oneshot then Exit;
      If Button8clickIsBusy > 0
        then begin
               Canvas.TextOut(10,10,'Drawing on Canvas');
               Caption := 'Busy ' + Button8clickIsBusy.ToString;
               Exit;
             end;
      //Canvas.Unlock; // may need
      Inc(Button8clickIsBusy);
      OneShot := True;
    
      const
        L = Shape1.Left + 5;
      const
        T = Shape1.Top + 5;
      var
        SP: Integer := 0;
      var
        X := -50;
      //Brush.Color := clmoneygreen;
      //Canvas.FillRect(BoundsRect);  //hosed by style and not max windowstate
      Repeat
        sX := X.ToString;
        Canvas.Font.Color := RandomFontColor;
        Canvas.Font.Size := X;
        Canvas.TextOut(20, 20, sX);
        canvas.DrawFocusRect(Rect(22,22,X+X-3,(X-3)*2));
    
        //on shape
        Canvas.Font.Color := RandomFontColor;
        Canvas.Font.Size := -X;
        Canvas.TextOut(L, T, sX);
        Sleep(20);
        Canvas.Font.Color := clWindowFrame;
        canvas.DrawFocusRect(Rect(22,22,X+X-3,(X-3)*2));
    
        Inc(X);
      Until x > 50;
    
      Button8clickIsBusy := 0;
      sw.Stop;
    
      Canvas.TextOut( 10,100,'Done et='+ sw.ElapsedMilliseconds.ToString);
      Caption := 'Busy ' + Button8clickIsBusy.ToString;
      Oneshot := False;
    end;

     

     

     

     

      

     

     

     

     

        

     


  8. I think this is a start Henney Lambda? Presentation 2020 NDC has mention of Borland's Pascal and Delphi in it. 

     

    Any computer based training, books, and manuals needs be to discussed over what was learned and review the topics that are unclear should make the onboarding process a learning experience for you as well as the new guy.   

     

    Also studying GExperts source and comments at https://blog.dummzeuch.de/2021/10/24/gexperts-1-3-19-alpha-for-delphi-11/   is good and what the Experts can do is useful!  

     

     


  9. Here's sample of updating lineseries and legend in real time   I think the data points should the numbers and be in the legend Second the time axis is usually bottom axis. For old data pass in the datetime of the record and field name of number.    

     

     

        s := FormatDateTime('ss', Frac(aSimTime));
        Ptp := Chart1.Series[0];
        if Ptp.Count > 300 then
          Ptp.Delete(0, 100);
    
        Chart1.Series[0].AddXY(now, FXY.y, s, clRed);
        Chart1.Series[0].Title := 'A ' + FXY.y.ToString;
    
        if Chart1.SeriesCount > 1 then
        begin
          Ptp := Chart1.Series[1];
          Chart1.Series[1].AddXY(now, FXY.y + 5, '', clBlue);
          Chart1.Series[1].Title := 'A dgr ' + (FXY.y + 5).ToString;
    
          if Ptp.Count > 150 then
    
            Ptp.Delete(0, 50);
        end;
    
      end;

     


  10. 5 hours ago, Fr0sT.Brutal said:

    Easy, just add some anime kitties and giant robots to win their hearts! Or... giant kitty robots!

    Psychic surgery may be indicated for those with bad luck. 🙂

     

    The only bad luck I know about is the disassembly window not showing on 12. Control-alt-d when stopped at a breakpoint only flickers the other debug floaters. 😞
     

    OIG.5.jpg

    • Like 1
    • Haha 1

  11. The try...finally...end is typically used to free memory. This sample simply sets the count back to zero and has a counter for number of count resets in the finally. Goto's and try's don't mix.

    var
      Count: 0..100 = 0;
      Reentrant: 0..100 = 0;
    
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      //Constraint
      If Count > 4 then
        exit;
      (Sender as TButton).Enabled := False;
    
      Inc(Count);
      Caption := 'Goingto ' + Count.ToString;
      Sleep(100);
      Try
        Caption := Format('Goneto  %d',[Count]);
        If Count < 9 then
        begin
          Sleep(110);
          Button2Click(Sender); //Poor Person's ProcessMessages
        end;
    
      finally
        Inc(Reentrant);
        Count := 0;
        sleep(12_00);
        Caption := Format('Please !gotos!* use %d jumps',[Reentrant]);
      End;
      //* pram notation Beattie
    
     //Enables first finally pass :(
     (Sender as TButton).Enabled := True;
    end;

         

      


  12. Here's some more Information for your consideration.

     

    Quote

    The problem with the lock-modify-unlock model is that it's a bit restrictive and often becomes a roadblock for users:

    • Locking may cause administrative problems. Sometimes Harry will lock a file and then forget about it. Meanwhile, because Sally is still waiting to edit the file, her hands are tied. And then Harry goes on vacation. Now Sally has to get an administrator to release Harry's lock. The situation ends up causing a lot of unnecessary delay and wasted time...

    https://svnbook.red-bean.com/en/1.7/svn-book.pdf  

     

    Surely only copies of your documents are being looked at and double checked before changes are recorded into the system.  


  13. On 11/6/2023 at 1:55 PM, Remy Lebeau said:
    On 11/6/2023 at 11:19 AM, RTollison said:

    reason for this is cloud server and multiple clients. we give them a specific folder that is theirs but if we allow them to navigate to other clients folders it presents a security problem.

    Letting a user even see that another user's folder exists, even if it's not selectable, is just bad UI design and broken security waiting to be exploited.

    I would change this to mean each client 'sees' only one 'cloud' or 'channel'. Meaning the Admin for one client's machines would never see another client's channel machines and data. Have each client users use email and password to start windows and access their file share and shared drives as allowed by the logon of that user's account. 

        


  14.  

    2 hours ago, PaulM117 said:

    PInteger(@IntArr[0]

    Shouldn't that be PNativeInt(@ to allow either 32 or 64 compiling. The first 12 compile for me was 11K bigger but additional recompile yielded 45k smaller exe*.  The displays show one NAN and blank "TokenWindow:bds.exe"

    *Did remove unused Controls from a package though.


  15. In the past using Showing property never worked well for me...  I just the removed the if Showing and just Hide and Show as needed.  

     

    Also I added Step, Run, Stop buttons for timer state.  A Step "freezes" the "program" if timer was enabled. If !timer.Enabled the Step does one OnTimer event. In runtime. 

    Or say in Edit mode vs "Freeze". The State machine tells the Windows tiling what to do.  The tiling should have not to deal with the State machine. This tiling either forms or controls get control when active or have focus.  UI is dealt by State machine. The tiler (UI) plays the cards dealt. 

     

    Also simply changing the parent of control can "show" or "hide" in a hurry.    

     


  16. 20 minutes ago, dummzeuch said:

    ...the internal timestamp of a dcu file is older than the currentl source code of a unit and recompiles it, if necessary. But what exactly does hat have to do with GExperts?

    I plan to code an expert to verify the dcus are kept current with current source code because sometimes the current source code needs saved before the dcus are recompiled. I need to simply review and learn more before making additional comment.

     

     

×