Jump to content

Anders Melander

  • Content Count

  • Joined

  • Last visited

  • Days Won


Anders Melander last won the day on September 20

Anders Melander had the most liked content!

Community Reputation

423 Excellent


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. Anders Melander

    More performance Stringgrid sorting algorithm help

    Yes. You are right.
  2. Anders Melander

    git workflow question

    It discards changes to all tracked files. Basically it makes sure that what you have on disk matches what's in your branch. You can also do a mixed reset. That moves the index in your commit history but keeps whatever you have on disk. Then there's a soft reset but I can't remember what that does as I never use it. The reason I'm doing a reset is that otherwise pull will do a merge with whatever I have on disk and that isn't what I want. I'm not actually doing anything since my tool does all this for me, but you get the picture. Personally I prefer Atlassian SourceTree. I have Tortoise Git installed as well because there are a few things it does better (Blame for one). I've not tried any of the commercial GUI clients. There was a thread here a few weeks back where different Git clients were discussed.
  3. Anders Melander

    More performance Stringgrid sorting algorithm help

    If you start with i := 1 then the 0 and 1 elements will always be swapped. If you then also change the test for (i = 0) to (i = 1) then the 0 and 1 elements will never be swapped. Try to run it in your head with just three elements in reverse sort order. iteration elements 0 3 2 1 i=0: inc ^ 1 3 2 1 swap and dec ^ 2 2 3 1 i=0: inc ^ 3 2 3 1 ok: inc ^ 4 2 3 1 swap and dec ^ 5 2 1 3 swap and dec ^ 6 1 2 3 i=0: inc ^ 7 1 2 3 ok: inc ^ 8 1 2 3 ok: inc ^ 9 1 2 3 done ^
  4. Anders Melander

    More performance Stringgrid sorting algorithm help

    Well now that I've had my fun here's a serious suggestion: type TGridCracker = class(TCustomGrid); procedure SortGrid(Grid: TCustomGrid; ACol: integer; Ascending: boolean); begin var Rows := TList<integer>.Create; Rows.Capacity := Grid.RowCount - Grid.FixedRows; // Populate list with row indices for var i := Grid.FixedRows to Grid.RowCount-1 do Rows.Add(i); // Sort the row indices Rows.Sort(TComparer<integer>.Construct( function(const A, B: integer): integer begin Result := AnsiCompareText(Grid.Cells[ACol, A], Grid.Cells[ACol, B]); if (not Ascending) then Result := -Result; end)); // Move the rows in-place to their new position Grid.BeginUpdate; try var ToIndex := Grid.FixedRows; for var FromIndex in Rows do if (FromIndex <> ToIndex) then TGridCracker(Grid).MoveRow(FromIndex, ToIndex); finally Grid.EndUpdate; end; end; I've not used TStringGrid in decades but I think it might be fast enough if you can get it to compile (I haven't tried). I'm assuming that the protected MoveRow method does what we need (i.e. move a whole row in the grid). It might not though. A minor optimization would be to use a TArray<integer> instead of a TList<integer> but the improvement would be minimal.
  5. Anders Melander

    More performance Stringgrid sorting algorithm help

    That won't work. You need to start at zero. That's cheating. Then you might as well just optimize it to use TList.Sort
  6. Anders Melander

    More performance Stringgrid sorting algorithm help

    Yes it's horrendously slow but if performance isn't important it's nice and short and easy to implement - if you can remember the algorithm. I've used it a few times in throw away production code just because I like its simplicity. Compare to how often people get quicksort wrong when they roll their own.
  7. Anders Melander

    git workflow question

    I don't do these thing from the command line, so I may be wrong, but it seems to me that you're: Switching the active branch to <ticket-branch-name>. Pulling the remote master onto it. Switching to master. Pulling the remote master again. Merging <ticket-branch-name> into local master. Pushing local master to remote master. I can't understand why you're doing 1-2. In particular #2 seems wrong. I think you may be creating foxtrot merges. Did you forget to commit your changes to <ticket-branch-name> before you switched to master? You haven't specified if your local branches are setup to track the corresponding remote ones. If they're not, and you haven't adjusted your git commands for that, then you might be working with detached heads. Anyway, here's what (I think) I would do: Switch to local <ticket-branch-name>: git checkout <ticket-branch-name> Make my changes... Stage my changes: git add <files> Commit changes to local <ticket-branch-name>: git commit -m "blah blah" Fetch master from remote: git fetch (or just: git fetch --all) Note that you you might need to do git fetch origin master:master depending on if your local master is tracking the remote master or not. Switch to master: git checkout master Clear all changes from working directory: git reset --hard Pull from remote master: git pull origin Merge local <ticket-branch-name> into local master: git merge <ticket-branch-name> Push local master to remote master: git push origin master Again: I don't use the command line so the above is just my understanding of what my GUI tool does for me. If you were using a GUI Git tool it would be much more clear to you what's going on.
  8. Anders Melander

    More performance Stringgrid sorting algorithm help

    Funny name you say? How about he optimize it with Gnome sort instead: procedure GnomeSort(List: TList<integer>); begin var i := 0; while (i < List.Count-1) do if (i = 0) or (List[i] >= List[i-1]) then Inc(i) else begin var Swap := List[i]; List[i] := List[i-1]; List[i-1] := Swap; Dec(i); end; end;
  9. Anders Melander

    "Self-updating" terminal services DLL

    MoveFileEx with the MOVEFILE_DELAY_UNTIL_REBOOT flag can do that already. Virtual Channel client DLLs are loaded at boot so it's pointless to try to replace the file without a reboot. That said, you could solve it with two DLLs: The Virtual Channel client DLL contains the auto-update functionality but forwards all the VirtualChannel* DLL calls to... The "other DLL" which implements the actual functionality. Of course the Virtual Channel client DLL will need to load the "other DLL" dynamically or you will have the same problem with both DLLs. When the Virtual Channel client DLL determines that it needs to update the "other DLL" it just unload the old DLL and load the new DLL. If the Virtual Channel client DLL needs to update itself it can do so with MoveFileEx (or just unregister the old DLL and register the new) and a reboot. Maybe it's enough to restart the Remote Desktop Services (the documentation just states that the DLL is loaded during Remote Desktop Services initialization), but you will need a third file, an application, that does that for you. Give it a try. Edit: I just realized that the above was basically what @Fr0sT.Brutal wrote.
  10. Anders Melander

    DFM Serialization Properties order

    Re: Plastic Merge. It appears that the free Personal Edition isn't available anymore. What you can do instead is download and install the Plastic client: https://www.plasticscm.com/download/downloadinstaller/ and then just use the Diff/Merge utility: mergetool.exe I've just tried a fresh install and it worked fine.
  11. Anders Melander

    DFM Serialization Properties order

    You can republish properties: type TLabel = class(TLabel) published property Caption; property Align; end;
  12. Anders Melander

    DFM Serialization Properties order

    AFAIR you just change the order in which the properties are declared. Note though that I've seen cases where a component depended on properties being set in a specific order during load. Can't remember any specifics. You could also use a diff tool that can recognize moves. For example Plastic Merge.
  13. Anders Melander

    MsgWaitForMultipleObjects Usage

    I'm not the OP. My example with MsgWaitForMulpitleObjects used QS_PAINT and DispatchMessage. The OP's use of QS_ALLINPUT is probably based on not understanding the problems associated with it. The circumstances where it's safe to Application.ProcessMessages are so rare that one might just as well not use it. Your example uses it in a button click handler where it's definitely not safe.
  14. Anders Melander

    MsgWaitForMultipleObjects Usage

    Oh no, you didn't!