Jump to content

Steven Kamradt

  • Content Count

  • Joined

  • Last visited

Community Reputation

6 Neutral

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Steven Kamradt

    Ignore exception type from code

    You asked how to ignore the exception type in that block of code. If you were using a compiler directive for a block of code you would also be making changes. I would actually suggest that your rule should be more of a guideline than a rule. If your maintaining production code, you really want your external components to also be in version control under the project they are being used in. Otherwise, how can you possibly make sure that you are rebuilding a specific version if you have to roll back to diagnose an issue in the field? How do you insure that anyone new to the team has the exact components installed? Often I have had the need to modify a 3rd party component or source to do what I needed and it was unique enough that the vendor wasn't willing to add support for my necessary changes. In the case where its a "bypass" for debugging, you can always revert your changes once your confident that its working properly unless its something you deal with every time you debug. Either way, if its in version control you have a diff with the changes and its not difficult to merge some minor changes in with the next component update.
  2. Steven Kamradt

    Project manager feature

    While I see what your getting at, this feature kind of already exists if you right click on the project, not the folder. When you add a new unit, it creates a dirty buffer that has not yet been saved. Saving it prompts you for the name, which defaults to unit1.pas (or next available number) in the project directory. In the save dialog its trivial to click on a folder (or create a new one) and save it there instead. The first thing I generally do when I create a new unit is save the file and give it a proper name and location. The folders don't show up until you add a file that is in a folder other than the dproj project folder location. As far as adding multiple existing units from a directory, I just drag and drop from explorer to the project and it "automagically" puts them in the appropriate folder (based on the existing location of course). Much simpler than clicking the button or right clicking to add to the project, unless its a one off.
  3. Steven Kamradt

    Ignore exception type from code

    You could just rewrite the CheckOSError line to: if TSynDWrite.GDIInterop.CreateFontFromLOGFONT(LogFont, DWFont) <> ERROR_SUCCESS then exit(False); and then the exception will not be raised by the CheckOSError function wrapper.
  4. Steven Kamradt

    Parnassus Bookmarks for Delphi 11 Alexandria?

    Really, all that is missing from this GExperts expert is mapping the CTRL-B to add a new bookmark (or if your on a bookmark already just remove it), and the concept of a bookmark stack (the ctrl-shift-b to drop a temporary bookmark, and escape to pop the bookmark stack, shift-escape would swap the current position for the last position). There was some custom drawing of the bookmark stack into the editor, which is possibly why we haven't seen it updated to Delphi 11.1 yet?
  5. I see nothing wrong with using absolute in this case, however you could make it a tiny bit stronger by placing it all in a class and hiding the storage. Maybe use TList as a starting point, but add accessor methods to fetch/append/insert/delete for each type. Keep a state variable so you know what mode its in and only have to switch modes when you change. Also, keep counts for each supported type so you can set the length appropriately. The list would always be an array of integers behind the scenes, but it then could contain an odd number of bytes or words. A ForEachByte or ForEachWord routine could be coded to use a stack to set and reset the state variable if necessary. I have done something similar with absolute when I needed to compare large blocks of data. An integer compares or moves at just short of 4x as fast as looping through 4 bytes. Disclaimer: This doesn't mean you should use this technique because you can. Its good practice to always measure to find the real bottlenecks and not add complexity to optimize when the net result is still nearly identical.
  6. Steven Kamradt

    Trial RAD 11 expired Delphi CE is 10.x

    I believe they are talking about the most recent version of the Community Edition, not the current paid version. The current community edition (as far as I can tell) is based on 10.4, not 11.x. See question 9 where it clearly states that the community edition is NOT the same as a trial of the latest release. In your quoted question the actual answer states that the community edition license is valid (ONLY) for the most recent community version not previous versions of Delphi regardless of community or not. Also keep in mind that a benefit of being on at least a professional sku is that you get access to the latest releases, which would include 11.1 and that a community edition license is only valid for a single year, at which time you must request a new license, and that license will be valid for the "most recent version" of the Community Edition.
  7. Well, since you opened this up for comments. 🙂 I think it would be useful to have some sort of indicator in the available units to show which ones are ALREADY in the interface/implementation. Maybe use italics or dark grey for any match? Or grey circle icons where either the top half or bottom half are a specific color if its used in the interface or implementation respectfully?
  8. Steven Kamradt

    INI problem

    Another trick is to use ExtractFilePath(paramstr(0)) to get the executable location. It really depends on your use case and how the executable is deployed. using your example above, this would be: TIFFileini:= TIniFile.Create(ExtractFilePath(paramstr(0))+'ComPortServer.ini');
  9. In your case, I would put the variables you are working with in a class or even a record and set the scope to what you selected as private to the thread. Keep it simple, its all about preventing access from multiple threads. If you have a global variable that needs to be accessed by multiple threads, protect the access using some sort of semaphore, such as a critical section or spin lock.
  10. Maybe a state variable and a work queue? You would add to the work queue the item that needs to be processed and its current state. Somewhere in your application (maybe a separate thread or on idle) loop through the queue and investigate each state to see if its eligible to move to the next state or be removed from the queue. If you persist this queue (database or file) you can then on program crash and reload determine if there is a state which would need to be restarted or not.
  11. First, lets agree to disagree. Yes, there is no problem with that pattern as long as it is used consistently for those forms. However, if you start to mix patterns with those forms, where sometimes you use the method you pointed out, and other times use the try/finally block with a variable you will likely run into AV when the destructor gets called twice in the later pattern (once on form close, then again on the explicit free). This is not something that is not always easy to find the cause of. Sure, if you have a small team or project it won't be that large of a deal, but if your project becomes more complex or has a larger team working on it the deviation from the norm can have an unexpected cost.
  12. The problem with above is that you will be scratching your head as to why you have AV's everywhere when you mix patterns, not to mention the fact that it will not be disposed of if there is an AV in the modal form. But we never have those do we. 🙂 The simplest solution is what Lajos Juhász suggests above. You could easily make this a standardized procedure or class method. I just wouldn't be afraid of the standard pattern, its simple and easy to maintain.
  13. A hash of the list would only tell you if the list was identical across all items. Keep in mind that any positive matches would have to be checked as it is mathematically possible to create the same hash value from different source values, more so if you are just using the DigestAsInteger function to grab a simple integer. Also, it is entirely possible to generate a hash value ANYWHERE in the integer range, so don't rely on any special values (for example, 0 is a possible result). If the lists have partial matches you need to report on, you could build a list of lists for each list. The idea is that each level would contain more information. So first list would be a single year and contain a list of months, which contains a list of days, which contains lists of hours, and the next level minutes. Each list can be a static array so there is no walking through the list, just checking against nil to see if that array position has a list (and potential values) or not. It has the disadvantage of using more memory, and requires time to build/destroy the list, but should be very quick to access. You just need to do a decodeDateTime to break a datetime into its parts, then use that to see if there is a value in the other list(s) that matches. The idea is to create something manageable and eliminate a need to loop and compare more than necessary. If you need to support multiple years, I would add another level to the start that would be a dynamic array of years and compute the array position as selected year - lowest year supported and grow your array as needed. if the year in the comparison list is outside of the bounds of that array, then it doesn't match anything that year.
  14. Steven Kamradt

    Parnassus Bookmarks for Delphi 11 Alexandria?

    And to twist the knife even deeper... I received a marketing email from Embarcadero today focusing on the Parnassus Navigator, saying how its available via getit, but in reality, no.... still nothing for Delphi 11... just 10.4.