Jump to content

PeterBelow

Members
  • Content Count

    468
  • Joined

  • Last visited

  • Days Won

    13

Posts posted by PeterBelow


  1. 49 minutes ago, Henry Olive said:

    I wish everyone a healthy day

     

    Edit1.Text := 'AA BB'

    MyVar := Trim(Edit1.Text);  // MyVar is still AA BB,  i was expecting to get AABB

     

    Thank You

    Are you looking for something like this?

    {! <summary>
    Remove all characters in aSet from the passed string and return the
    resulting string</summary>}
    function RemoveCharsInSet(const S: string; const aSet: TSysCharset):string;
    var
      I: Integer;
    begin
      Result := S;
      for I := Length(S) downto 1 do
        if S[I] in aSet then
          Delete(Result, I, 1);
    end;
    
    {! <summary>
     Remove all characters considered whitespace from the passed string
     and return the resulting string</summary>}
    function RemoveWhitespace(const S: string):string;
    const
      Whitespace = [#0..' '];
    begin
      Result := RemoveCharsInSet(S, Whitespace);
    end;

     


  2. 5 minutes ago, JkEnigma said:

    Hi all,

    Currently, I am using Free Pascal but I realized that Delphi has several possibilities that would come in handy for me. I would like to give the Community Edition a try. However, I still remember using the free version of Borland Delphi which was discontinued after Delphi moved to CodeGear. That is a long time ago and Embarcadero is another company, but still...

    Does anybody have information about the long term availability of the Community Edition? 

    TIA

     

    It's difficult to make predictions, especially if they concern the future :). What may be important to know for you is this, however:

    The licence for the community edition cannot be renewed; if you need to install it on a new computer you need to get a new licence key, which is no problem, however.

    When a new Delphi/RAD Studio version comes out there is also a new community edition, usually available after a short delay. The previous version's community edition is then no longer available and you cannot get new licence keys for it anymore, so have to move to the latest edition if your old licence expires (it is limited to 1 year if memory serves).


  3. 7 minutes ago, Henry Olive said:

    I wish everyone a healthy day.

     

      S:= Edit1.Text;  // which is  A1 A2 A3 A4

      with below code i get only  A1 but i need to get A1 A2 (First 2 words )
      X:=Pos(' ',S);
      Left2Words:= Copy(S,1,X-1);
      Edit2.Text := Left2Words;

     

    Thank You

     

     

     

     

    I think the best way is to dissect the input into "words" and then assemble the parts you want from that list.

     

    procedure TForm1.Button1Click(Sender: TObject);
    var
      LWords: TStringlist;
    begin
      LWords := TStringlist.Create();
      try
        LWords.Delimiter := ' ';
        LWords.DelimitedText := edit1.Text;
        if LWords.Count >= 2 then
          edit1.Text := LWords[0] + ' ' + LWords[1];
      finally
        LWords.Free;
      end;
    end;

    Note that there also is a

    function PosEx(const SubStr, S: string; Offset: Integer): Integer

    in unit System.StrUtils that allows you to start the search at a position other than 1.


  4. 1 hour ago, Henry Olive said:

    I want to Filter a Dataset 

    When user click the DBGrid's *desired title (Column)* i want to show a PopUpMenu

    according to its place in the dbgrid's column

    I write below code

    procedure TForm1.DBGrid1TitleClick(Column: TColumn);
      var
      p:TPoint;
    begin
      if Column.FieldName ='TNAME' then

        p:=DBGrid1.ClientToScreen(Point(0,DBGrid1.Height));
        Pop1.Popup(p.x, p.y)

    end;

    With above code PopUpMenu PopUp sometimes Above, sometimes below of the dbgrid

    I need the PopUpMenu PopUp according to its place in the dbgrid's column

    Something like below

      p:=DBGrid1.Columns[1].ClientToScreen(Point(0,DBGrid1.Columns[1].Height));


    Try this:

    
    type
      TGridCracker = class(TDBGrid);
    
    
    procedure TForm1.DBGrid1TitleClick(Column: TColumn);
    var
      LPoint: TPoint;
      LRect: TRect;
    begin
      LRect := TGridCracker(Column.Grid).CellRect(Column.Index+1, 0);
      LPoint := Column.Grid.ClientToScreen(LRect.TopLeft);
      LPoint.Y := LPoint.Y + TGridCracker(Column.Grid).RowHeights[0];
      PopupMenu1.Popup(LPoint.X, LPoint.Y);
    end;

    Unfortunately TDBGrid offers no easy way through public methods or properties to get at the screen coordinates of a cell, so one has to fall back to protected methods inherited from TCustomGrid. The advantage of CellREct is that iot also works correctly when the grid is scrolled horizontally.

     

     

     


  5. 18 hours ago, EugeneK said:

    Hi

     

    When using TEdgeBrowser directly it is possible to set custom UserDataFolder property value. Is there a way to set it when using TWebBrowser with Edge engine? (Delphi 11 if that matters)

    Well, TWebbrowser (in D11) has a protected method

        function GetEdgeInterface: TEdgeBrowser;

    To get at it you can use a cracker class, e.g. declared in the implementation section of the form unit containing the TWebbrowser control.

    type
      TWebBrowserCracker = class(TWebbrowser);

    In your code you can then do something like

    var Edge: TEdgeBrowser := TWebbrowserCracker(Webbrowser1).GetEdgeInterface;
    if Assigned(Edge) then begin
      Edge.UserDataFolder := SomeDirectory;
      Edge.ReinitializeWebView;
    end;

    Completely untested, so use at your own risk!

    • Like 2
    • Thanks 1

  6. 19 hours ago, Anders Melander said:

    The possible race condition I referred to has to do with the (presumably reference counted) lifetime of InternalHelperRegistry but since I haven't looked at the rest of the code there might not be a problem - for example if InternalHelperRegistry is guaranteed to stay alive elsewhere.

     

    With regard to locklessnes, doesn't the instantiation of an object cause a lock in the memory manager?

    InternalHelperRegistry  is a "global" variable declared in the implementation section of the unit and will stay around for the lifetime of the application; it is set to nil in the unit finalization.

    It has been some time since I last looked at the memory manager implementation, but a lock there does not protect against a race condition in the code assigning the resulting reference to a variable elsewhere.


  7. 10 hours ago, Anders Melander said:

    Yes it does seem to come from that SO thread. The problem as I see it is that it mixes a lock free solution, that's meant to operate on pointers, with reference counted interfaces. Also I don't like the practice of creating an object and then freeing it if it's not needed anyway, but that's besides the point.

    Well, interface references are  pointers, so the problem is just how to make sure the reference count stays correct, which the code does.

    The singleton template the code was created from is quite old, however, predating the appearance of TMonitor by several years. There may be a cleaner way to implement this these days, but I don't like to change working code if there's no pressing reason to do so. :classic_dry:


  8. 23 hours ago, Alexander Elagin said:

    Does not compile in 10.1 because of inline variables. What was the reason to use the cosmetic feature only available in the latest versions?

    That code comes from the forin template that comes with newer versions of Delphi. Sorry for the inconvenience, but since I program mostly for my own use i'm not much concerned with compatibilty with older Delphi versions and simply did not notice this as a potential problem.

    • Like 1

  9. SudokuHelper is an application that acts like an electronic Sudoku grid. It supports 9x9, 12x12, and 16x16 Sudokus, both in the classic and Gosu variant, where cells can be marked to only accept even numbers. The application neither creates Sudokus itself nor provides a solver for them; it is just a more convenient way to solve a Sudoku from a magazine or other external source than doing it on paper, using pencil and eraser.

    The application's main features are:

    • Invalid cell values are marked in red.
    • Candidate values can be added and removed from a cell. Setting a cell's value will automatically remove candidates no longer possible in other cells.
    • All actions can be undone, the undo stack is only limited by available memory.
    • Named marks can be set for the current undo stack state and one can later restore the stack to such a named mark.
    • The complete Sudoku can be saved to file, including the undo stack, and later loaded again from such a file.

     

    The project can be found on GitHub: https://github.com/PeterBelow/SudokuHelper

    The code is a good example (IMO) of how to uncouple the UI from the "buisness" code using interfaces, in a kind of MVC design. It is free (public domain) without restrictions.

    • Like 2
    • Thanks 1

  10. 19 hours ago, Bernard said:

    Hi Guys thanks for the swift replies and sorry for the delay in getting back to you all.

     

    When I do not call the loadfile; Focus remains on the TFileListBox component as is expected;

     

    When I do call the Loadfile on its own...

    The loadfile loads a cadfile into an activeX component and at this point focus is lost. 

    I have also noticed that, at the point focus is lost, the tab button no longer gives focus to any of the other controls on the form.

     

    The activex control is a visual control EWDraw 3D.

     

    Is there something I am missing in the activeX end.  Do I need to catch the tab key and send messages from its keyboard event?

    That sounds as if the form is no longer the foreground window after the ActiveX control hasloaded the file.  Try to add a

    BringToFront;

    after the LoadFile line.


  11. 12 hours ago, Ian Branch said:

    Hi Team,
        An interesting observation..
        D10.3.2.  Win 10.
        Main Form with a MainMenu.
        If I call Form 1 from the MainMenu top line option, lets call it 'Form 1', using "TForm1.Create(nil).ShowModal;",
        and then from Form 1, call Form 2 with a TButton using "TForm2.Create(nil).ShowModal;",
        and then try to have a PopMenu appear in Form 2, it doesn't/won't.
        If, however, I repeat the above but make the initial call from a MainMenu sub-menu, Form 1|Form 1', then the Popup menu works in Form 2.

        This is repeatable.
        Is this normal or a bug?

    Regards,
    Ian

    Did you remember to set the PopupMode property of your modal forms to pmAuto? What you describe sounds like a Z-order problem. But I see from the newer messages that the problem spontaneously resolved itself. It always makes me nervous when that happens in my projects...

    • Like 1

  12. Look at the Format function, it can be used to compose a string from values/variables using a template string with placeholders, taking the values to insert via an open array parameter. That covers all standard simple datatypes, but complex types like objects, arrays, dictionaries usually have no default method to convert their content to a string (although some have a ToString method, natively or through class or record helpers). For your own classes you can override the ToString method inherited from TObject, for instance.


  13. On 9/22/2019 at 6:26 PM, Larry Hengen said:

    I have a TForm descendant that contains a scrollbox, and the form is nested within two panels on the main form of my application.  It displays values in a manner similar to the object inspector, and the user needs to be able to edit the values.  For some reason, I cannot focus the TLabeledEdit controls using the mouse left button click.  Right clicking on the control works and selects all text in the TEdit, but left click does not.  I see that a WM_SETFOCUS message is sent, but false is returned.  Before I start digging into the the VCL's message handling, I was wondering if anyone might know the cause of such behaviour, or have suggestions on how to best track it down.

     

    I just converted the "inspector" form to a TFrame.  In doing so I loose some functionality like the ability to close the form, but I can now focus the edit control using the left mouse button, and I also get a right click local menu for the editor.  Is there anyway to make the embedded form behave in the same way as the frame with respect to embedded controls?

    Maake sure you set the form borderstyle to bsNone, so it has no caption bar. Windows does not like controls with the WS_Caption window style (and that is what the form becomes when you embed it), they have focus issues likr the one you observed.

    • Thanks 1

  14. Well, there is a FileSearch function in Sysutils that will search for a file in semicolon-separated list of directory names, but of course you still have to extract the library path from the IDE settings (= registry key, specific for an IDE version), the search path from the current project, if relevant, replace any macros ($(name)) in the pathes etc. to get the list of folders. I'm not aware of a ready-made function for this exposed in the RTL or Open Tools API.

     


  15. 1 hour ago, Der schöne Günther said:

    But wouldn't that require the "CallerThread" to support something like this? As far as I know, only the Delphi main thread has something like this, queueing/synchronizing something to a regular TThread has absolutely no effect.

    Yes, it is far from easy to switch processing to a specific secondary thread. Basically it is only possible savely if that thread has been written for this.

     

    So i can only concur with your previous reply: the responsibility of handling the synchronizing should fall to the code providing the callback.

     


  16. 14 hours ago, David Heffernan said:

    Why even bother writing those checks? An exception will be raised as soon as you attempt to use the nil instances. 

    Yes, but the error you get then will not immediately indicate what the problem is. The way I do it its clear that the problem is a contract violation, and one can write unit tests that check whether the method correctly detects a contract violation.


  17. 15 hours ago, David Schwartz said:

    Well, aside from a general sense that exceptions shouldn't be used for flow control ... 

     

    Anyway, I'm looking for some examples as well. This is not a topic that is very widely discussed, although for lots of projects I've worked on, they've devised some kind of consistent approach, usually NOT based on exceptions. But many haven't, so you can see personality differences in the code depending whose favorite method for vetting incoming parameters was used.

     

    This isn't very Delphi-specific, so discussions about it in other languages would be fun to read, too.

     

    I usually test for pre and postconditions like this:

     

    procedure TBlobDB.CreateNewDatabase(aDBStream, aIndexStream: TStream;
        aTakeStreamOwnership: boolean);
    const
      Procname = 'TBlobDB.CreateNewDatabase';
    begin
      if not Assigned(aDBStream) then
        raise EParameterCannotBeNil.Create(Procname,'aDBStream');
      if not Assigned(aIndexStream) then
        raise EParameterCannotBeNil.Create(Procname,'aIndexStream');
    

    This is for errors that are supposed to be found and fixed during the testing phase or (for library code) in unit tests. For user input the input is validated before it is used by the program, if this is at all feasable. The end user should never see an exception coming from parameter validation at a lower level, in my opinion, since the UI context may not be evident at that point and it may be unclear to the user what he did wrong.

     

    • Like 3
×