Jump to content

MarkShark

Members
  • Content Count

    86
  • Joined

  • Last visited

Posts posted by MarkShark


  1. The situation:

    I'm trying to emulate a combobox using a buttoned edit control and another parented control as the "box".  This works fairly well, but I want to handle the standard Windows combobox hotkeys for toggling the box visibility which are F4 (easy) and Alt-Up/Alt-Down (much less easy as it turns out since I almost always use the up down arrows on the numberpad.)

     

    The problem:

    Using Alt-Up and Alt-Down from the numberpad (as opposed to the up/down dedicated keys) generates alt code characters.  This happens even if the numlock is off (I was surprised by this.)

     

    The only solution I've found:

    I'm just filtering out the possible alt-code characters in OnKeyPress.  This isn't ideal as if you hold down Alt and just hit up or down like crazy you can generate a large number of different characters, and I'd like to filter them all or come up with a much better way than an overly large case statement.

     

    Any thoughts or ideas?

     


  2. I did a lot of trial and error while working on the scrollbars for SynEdit and setting min to 1 seemed necessary.  The code I ended up with is in SynEditScrollBars.   The official documentation did seem a bit off in some cases.

     

    -Mark

     


  3. Just wanted to mention that I realize I can add a notification handler to the entire FWorker with:

     

      FWorker := Parallel.BackgroundWorker
        .NumTasks(1)
        .TaskConfig(Parallel.TaskConfig.OnMessage(HandleTaskNotification))
        .Execute(HandleQueryWorkItem);

    But I'm wondering if I can do a WorkItem specific handler with the Schedule() call.


  4. I currently have a background worker that I use to serialize a queue of workitems.   The code to create the worker is:

      FWorker := Parallel.BackgroundWorker
        .NumTasks(1)
        .Execute(HandleWorkItem);

    In this case the HandleWorkItem method is just a dummy method as I actually pass in the workitem code when I schedule the workitem.  E.g.:

     

      FWorker.Schedule(
        FWorker.CreateWorkItem(TOmniValue.FromRecord(MyWorkItemDataRec)),
        FWorker.Config.OnExecute(
          procedure(const workItem: IOmniWorkItem)
          var
            TaskResult: TTaskResult;
          begin
            // Do a bunch of work here in a background thread 
            // Now set the Result TOmniValue from a record.
            workItem.Result := TOmniValue.FromRecord(TaskResult);
          end)
        .OnRequestDone(DoneMethod)
      );
    end;

     

    This works extremely well, but I'd like to notify the calling thread of the progress.  I thought maybe that IOmniWorkItemConfig would have an OnMessage(eventHandler: TOmniTaskMessageEvent) that I could set during the Schedule call (much like OnRequestDone) but I haven't figured out how to do that.

     

    Any help or suggestions appreciated.

     


  5. Blast from the past!  I worked at the Lab of Computer Science at Mass General Hospital right out of College (a great place with wonderful people.)  I worked on Mumps for a few years back then.  The database for Mumps/M is a hieratical database and it's not easy to do a direct translation to a relational database (based on knowledge from 30 years ago so it might be completely out of date! lol)  In any case, I might look at Zeoslib instead of Firedac since it's open source and might be easier to create a new driver with.  Sorry to not be more helpful!


  6. As of Delphi 11.2 they fixed the wholeword option handing (https://quality.embarcadero.com/browse/RSP-20731) however they changed the way that SelStart works when searching backwards (its' now -1 based instead of zero based..)  To fix it to match the earlier behavior you have to do something like:

     

      if soDown in StringOptions then
        Result := SearchBuf(Buf, BufLen, SelStart, SelLength, SearchString, StringOptions)
      else
        Result := SearchBuf(Buf, BufLen, SelStart - 1, SelLength, SearchString, StringOptions);
     

    Basically, when searching backwards a SelStart of zero means to start the search at char position 1.  Maybe there's some reason to make it work that way, but it's a change from earlier versions where searching forwards and backwards used the easier to understand base of zero as the start of the search.  I haven't created a bug report for this as I had some problems with attempting to do it recently.   Also is there a way to do an ifdef specific to 11.2?

     

    • Thanks 1

  7. I was writing a simple record helper for TBytes and realized that some of my routines call SetLength.  I'm wondering if this is a problem since the array could/will be reallocated in memory.

     

    Simple example:

      TTestBytesHelper = record helper for TBytes
      private
        function GetLength: Integer; inline;
      public
        function ReadFromStream(AStream: TStream; ACount: Integer): Integer;
        property Length: Integer read GetLength;
      end;
    
    { TTestBytesHelper }
    
    function TTestBytesHelper.GetLength: Integer;
    begin
      Result := System.Length(Self);
    end;
    
    function TTestBytesHelper.ReadFromStream(AStream: TStream; ACount: Integer): Integer;
    begin
      // Wondering about this SetLength call!
      System.SetLength(Self, ACount);
      Result := AStream.Read(Self, ACount);
    end;

    In my testing the ReadFromStream function does seem to work fine.  I'm just wondering if calling SetLength on Self while in a record helper is ok to do.  Thanks for any insight!


  8. I use Project Magician, but I don't use custom manifests, so this may or may not be helpful!  In the help file it mentions that the child configurations cleaning setting "Application Settings" affects Icons, Manifest File, Output Settings and Appearance, and so that setting is probably what's clearing the child settings in this case.  You can clear that setting to see if it helps.  What I'd love is for Uwe to open source the tool, but it's definitely been useful to me "as is".  I use addition custom .optset files to set version info and such but doing so is undocumented at best.

    • Thanks 1

  9. Hey @aehimself

     

    SynEdit does have the SQLHighlighter which can give you some context information about the SQL, but it doesn't really have a full SQL script processor.  Have you looked at the one in ZeosLib?  I don't use it for my stuff as I had written one for Oracle's scripting language way back and then adopted it for the other databases with my newer products.   Note that you will have to use some sort of statement terminator (which can be as simple as a semicolon or it can be super complex with Oracle's SQLPlus syntax or less complex with a standard "set terminator" type statement.)  My tools are Golden (for Oracle) and GoldSqall (for Oracle, PostgresSQL, Firebird, MySQL, etc) and they all have to do exactly what you're doing.

     

    -Mark Ford

    Benthic Software

     


  10. My testing with MaxUndo = 1 (to most closely match a TMemo) doesn't show any leaks.  I've also tested the other scenarios with no leak issues that I could detect.  It's very true that the default settings can chew through a lot of memory for the undo stuff, so in the case of a log like this you must limit or manage the undo.  On a related note:  Am I correct that LockUndo/UnlockUndo must always be followed by a ClearUndo in order to keep everything in sync?  I wasn't' sure if that happened automatically or perhaps is just not an issue.

     

    -Mark

     

    @pyscripter

    I'm very impressed by how few issues there have been for such a major rewrite!  Well done!

     


  11. This is going to sound like a homework assignment, but it's actually needed for some ZeosLib code to handle PostgreSQL client library digital array format.  The array information is the following:

     

    NDims:  The number of dimensions:   Example: 3

    DimArray:  An array of dimension sizes.  Example [1,2,2]

    ItemsArray:  An array of data items (say Integer.)  Example: [1,2,3,4]

     

    I'm trying to figure out an algorithm to turn the information above into a string that has a format like: {{{1,2},{3,4}}}.  I've got it working for 1 and 2 dimensions, but it seems like I'm brute forcing it when it seems like a more clever approach should be possible.   Any tips, hints, or psuedo-code (or actual code!) appreciated!


  12. It sounds like it's a component streaming property error.  Make sure to open each form that has a SynEdit on it in the Delphi IDE and then save the form.  That should fix any of those types of errors.  Another thought is to make sure you have the latest version and to build and install the packages.


  13. I realized in my benchmarking above that I was comparing a case insensitive dictionary to a case sensitive one.  After correcting that the performance improvement for using this technique is 30%, which is still significant, but not what I reported above for sure lol.  I do notice something odd.  I'm loading about 300 SQL keywords (select, from, etc.) into a dictionary<string, integer> and if I check FKeywords.Collisions I'm getting a result of 90.  Looking at the code for TDictionary it looks like they take the results of the hash and convert it a positive integer for the array of buckets (I hope that's the correct terminology.)  I *think* that's where the collisions come in.  It looks like Spring4d doesn't have the collisions property, so I haven't been able to do a sanity check against it. 


  14. @Stefan Glienke Thank you!  My code is very close to yours, which is a nice validation for me lol.  I also put the "stored" string in the record (@Frost I also tested keeping them in a separate list to remove the record being managed, but it didn't seem to make any difference when I benchmarked it.)  I would be using Spring4D for this in my own code, however it may end up in SynEdit's highlighters and so I'm trying to keep dependencies down and to leverage the rtl as much as possible.

×