Jump to content

mikerabat

Members
  • Content Count

    45
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by mikerabat


  1. I had recently a similar problem! Random access violation although I thought my code was clean....

    My code was clean the problem actually was that the toast notification did something similar as

    Application.ProcessMessages! During the show or hide functions the Delphi message pump was active

    and if there were messages left that invoked the toast notification to change I ran into access violations on the

    Microsoft implementation side!

     

    So for a certain time one needs to process messages but make sure that nothing is called on the tost notification side

    for about 50 to 200ms....

     

    Here my original problem:

     


  2. You can use Webauthn/Passkeys/Fido2 keys . The only thing stored on the server would be a publik key that has been created on the client device!

    So... no need to store passwords on the server side 😉

     

    I got the webauthn api and a wrapper for the yubiko fido2.dll here.
    https://github.com/mikerabat/DelphiFido2

     

    and a (not so practical but good enough for me) example on how to use a passkey from the iphone here:

    https://github.com/mikerabat/fronius

    • Like 2
    • Thanks 1

  3. I didn't knew that this would trigger such a response gg

    Hi Stephan! Will there be some code to examine 😉 Quite good numbers 🙂 !!


  4. 22 hours ago, PeterBelow said:

    Then why don't you delegate the hint showing to a task running in a secondary thread? The task can wait for a short interval and if it is cancelled before that interval has elepsed the hint will not be shown at all... 

    As I see that this is the same mechanism just not in the main thread.


  5. Thanks for the suggestion. I'll try that one though I think it will not solve our problem in the first place - we already use the TTrayIcon component that allows to show balloon hints in the tray.

    BUT... (there is always a but..) we have a hard time to cancel the hints if they occure in a rapid way. That was no problem in winxp and win7 - there it worked well - but on newer

    OS's the tray does not cancel properly but rather shows the hint for a few seconds. This is quite annyoing for users since all the action has already been done and the hints still pop up.

    Note that we do not know in beforehand how long the hints are shown - sometimes it takes long (depeding on the amount of data transferred) sometimes it is fast...

     

    The newer toast notifications seem to resolve that problem but have this other nasty problem ... Anyhow I think the last change did the trick...


  6. Following problem:

    Our main platform for developing our applications is still D2010 (don't ask why..). One of our

    applications we develop used to use the standard tray icon ballon hints which have a few problems

    on newer platforms - win 11 especially.

     

    So.. the task is to use the toast notification component from D11. To do that I ccreated a small dll that exports a function

    returning an interface that handles the notification - basically show and cancel the hint.

     

    There are some events that may happen in a rapid timing. I carefully designed the dll such that the notifications are only shown and hidden

    in the main thread. The problem is that I encounter sometimes nasty access violations that I cannot account for...

     

     

    Here is my theory:

    Showing and hiding toast notifications through the winrt api somehow invokes something like Application.processmessages -

    I can confirm that during the hide call the show call is reentered (since I put something from a thread in the message queue

    that triggers a balloon hint to be shown) so either the show call or the hide call result in a nasty AV. (one call on the toastnotification center is not finished and 

    the next one is already there...)

     

    I tried to "wait" for the call to be finished but spin waiting blocks the notification stuff too and I actually do not want to have another

    handler implemented in the d2010 app....

     

    Has anyone experienced something like this (aka is there an easy solution)

     

    Could a queue be a solution -> the main app just queues the call an in a message pump (wndproc of an allochwnd call) I handle it myself?

    Any chance that some winrt init call is missing or can be done different such that it does not show that behaviour?

     

    Attached the two files that account for the dll

     

    kind regards

        Mike

     

     

    notifyImpl.pas

    trayNotifications.dpr


  7. I'm not sure about exactly this library but some predecessors indeed were able to sort pointer list whereas the "key" is a float/int 32/64 . The key can be specified as an "offset" to the

    starting address -> this allows to sort pointers to records/classes....

    at least that is the way they do it in "Fast quicksort Implementation using AVX Instructions"

     

    The definitions in the library for AVX512 are actually using arrays of templates so I guess that means that you can sort records right not only Double/float... ?

     

    On 11/3/2023 at 1:23 PM, DJSox said:

    In statistics and/or data analysis to calculate the median you have to sort the data, at least I always have. When plotting data, say in an xy plot, sometimes it's better to sort the data by x first. So, in technical fields it's not that uncommon.

    This problem is solved by an algorithm that allows to extract the kth largest element (not only the median) -> basically it does the partitioning of quicksort but does not sort hte "unnecessary" half. That in fact allows to pick the median in O(n) (roughly) time....

     

    And if you want to go fancy you can do a rolling median over an array of doubles. The algorithm can be found here:
    https://github.com/mikerabat/mrmath/blob/master/RollingMedMean.pas

     

     


  8. Jus FYI: That is intentional - the left side shall show the original assembler call the right side the DB translation

    -> my tool, that derrives the DB statements from the assembler code does a line by line comparison.

     


  9. Sorry... the tab key is broken or at least behaves completly different than in Delphi 2010 (or afaik Delphi 10.4) which is ... anoying.

    e.g.:

    Consider the following code

     Result := Format('%s;%s;%s', [
                               DateToStr( fDay, Fmt),
                               TimeToStr( fFrom, Fmt ),
                               TimeToStr( fTo, Fmt )  ]);

     

    when you place the cursor just behind the '[' bracket and then press enter the cursor is placed just below the R of Result... so far so good.

    But... In previous Delphi versions - when tab is invoked - the cursor jumps to the ":" then to "F" of format. Now the tab just moves the cursor

    by 2 (acording to the setting) which is actually anyoing.

     

    Another case: Consider the following code (we like to have the then else block that way in case the statement is only one line aka without begin end):

    if fLunchLen > 0.01
    then
           Result := Result + Format(';%s;%.1fh', [TimeToStr(fLunch, Fmt), fLunchLen], Fmt)
    else
          Result := Result + ';;'; // no free lunch... it bloody friday!

     

    When you place the cursor behind then, press enter -> press tab in previous delphi versions the cursor was placed just right below the then... now it only jumps by 2.

     

    any comments on how to get that old behaviour back is highly appreciated...

     

    kind regards

      Mike


  10. You could do something like CBOR encoding does. Basically there they encode values based on the NEEDED space.

    If integer then encode it in an int8 - to int16. You can also check if the encoding would fit into a 16bit float (half a single)

     

    In addition it seems that a differential approach for each block could be feasable ... does it change much??

    And of course at the end just compress the stream 😉


  11. Hey! We actually use the following code to get the system serial - maybe that can help:
     

    function GetSystemSerial : string;
    var FSWbemLocator : OLEVariant;
      FWMIService   : OLEVariant;
      FWbemObjectSet: OLEVariant;
      FWbemObject   : OLEVariant;
      oEnum         : IEnumvariant;
      iValue        : LongWord;
    begin
         CoInitialize(nil);
         try
            result:='';
            FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
    
            // ATT: we had a case, where on a Win2016 server, the system service failed to
            //      execute this command. Changing the service to a local user solved the problem.
    
            // There has been 2 cases where the WMI service was corrupted or was not running.
            // -> to check: enter WmiMgmt.msc in the console and right click on the local wmi - control -> Properties
            //    if an error occurs the repository seems to be corrupt
            // one time it helped to reset and rebuild the repository:
            // https://techcommunity.microsoft.com/t5/ask-the-performance-team/wmi-rebuilding-the-wmi-repository/ba-p/373846
            try
               FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
            except
                  on e : Exception do
                  begin
                       OutputDebugString(PChar('WMI service not properly running: '+e.Message+#13#10+
                         'https://techcommunity.microsoft.com/t5/ask-the-performance-team/wmi-rebuilding-the-wmi-repository/ba-p/373846'));
                       raise;
                  end;
            end;
    
            // todo: if we still support winxp this wmi class is not supported?!?
            FWbemObjectSet:= FWMIService.ExecQuery('SELECT UUID FROM Win32_ComputerSystemProduct','WQL',$00000020 {wbemFlagForwardOnly});
            oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
            if oEnum.Next(1, FWbemObject, iValue) = 0 then
               result:=String(FWbemObject.UUID);
         finally
           CoUninitialize;
         end;
    end;

     

    There is also another place where you could get some unique id:
     

    // from http://www.nextofwindows.com/the-best-way-to-uniquely-identify-a-windows-machine
         with OpenHKLMReadOnly('SOFTWARE\Microsoft\Cryptography', True) do
         begin
              AktMachineGuid:=ReadString('', 'MachineGuid', '');
              Log('Machine guid: ' + AktMachineGuid);
              Free;
         end;

     

    hope that helps!

     

    kind regards

      Mike

    • Like 2

  12. I'm puzzled... Since Delphi 11 the tab key does not work as it has been the case in all

    the previous versions... I tried to setup the editor options the same way as my Delphi 2010 (or 10.4)

    installation but the tab key behaves differntly....

     

    What I actually want is that when I press tab the cursor shall be placed after the last non whitespace from the previous line

    e.g.
    if you have

    var i : integer;

    begin

    |<- cursor here

    now when pressing tab the cursor shall jump the character after the n

     

    Also in Delphi 2010 it was standard if:

     

     if abc then

     begin

             while i < 10 do

             begin

    |<- e.g.: cursor here

             end;

     

     

    now the first tab jumps just right below the b of begin, a second tab to the end of begin

     

    That was standard for us for up until Delphi 10 ... but now in Delphi 11 I cannot get this working.

    it either works or it jumps the number of characters that has been defined in the TabStop field.

     

    anyone has a clue what there coudl be the problem?

     

    A also have DDevextensions and gexperts installed....

     

    kind regards

       Mike

     

     


  13. Thanks Remy!!

     

    Right... the call to BeginThread actually suceeds - the callstack clearly indicates that it's the ResumeThread call that fails.

    So... the only thing I found online was that there is a right  " THREAD_SUSPEND_RESUME " which may have

    some influence here... But I have absolutely no idea what could change that.

    Note that the code actually works on around 8k of installations but there are only a few (2 for now) that seem to

    make trouble in that regard. The thing is that if there are way fewer files to be loaded (e.g. 6-8) it works most of the time

    (aka not always)... Also the system worked for 2 years now without any problems... so I'm quite stunned that now something pops up.

     

    So... Is there any 3rd party or any configurable restrictions on Windows that disallow something like releasing many threads at once?

     

    kind regards

      Mike

     


  14. Hi all!

     

    In our system we load a bunch of files on startup in parallel so for each of these files we craete a thread

    that does that in the background.

     

    basically this is what how it is done:

    TEVentChannel is the data object that holds the data

    -> on the data object creation a thread (TEvtLoadThread = class(TThread)) is created which does the loading

    -> of course it is ensured that data access and loading is mutal exclusive.

    The snippset of code that is involved is:

     

    constructor TEventChannel.TEvtLoadThread.Create(parent: TEventChannel);
    begin
         fParent := parent;
    
         inherited Create(False);
    end;
    
    procedure TEventChannel.TEvtLoadThread.Execute;
    begin
         NameThreadForDebugging('Load '+AnsiString(fParent.ChanName));
         // ###########################################
         // #### Just start loading the data
         try
            fParent.Reload;
         except
               on E : EChannelException do
               begin
                    fParent.fLoadFailed := False;
                    fParent.fDataLoaded := lsBadRecId;
               end;
         else
             // damaged file??
             fParent.fDataLoaded := lsAll;
             fParent.Clear;
    
             fParent.fLoadFailed := True;
         end;
    end;

     

    My problem here is that on a system on which that code ran for over 2 years without problems now happens to fail with the error

    "Cannot call Start on a running or suspended thread"

    This error is issued in the TThread.Afterconstruction call and it seems that our system fails to create that thread...

     

    Looking at the TThread code it is most likely that the Thread could not be created so what on earth could be could interfere here?

     

    We tried to disable FSecure (or at least they claim no security system is monitoring our program) and Windows Defender without any change.

    Is there anything known out there that could limit an external program in such way?

     

    kind regards

      Mike

     

     

     


  15. Short answer ... yes - if you got simultaneously more connections from clients than you have requests handles in Delphi then an

    exception will be raised... Actually I find that property very stupid at all... e.g. apache creates on startup those 50 threads beforehand

    waiting for incoming connections. On each request a WebModule object will either be taken from the cache or created and put into the

    cache so this number should be either growing to the demand or be set to the number of the maximum active connections

    the server is allowed to serve.

×