You might soon have a few new "tips and tricks" items of your own with this conversion of yours. I'm guessing it is an older Delphi project? Hopefully not too many things like this to keep tripping you up!
Yes, it is definitely an older Delphi project, in a product that I sell, which is an encrypted, protected system for upgrading microcontroller firmware in the field.
For new projects, I have indeed switched to Unicode strings, but for backward compatibility, I used the AnsiString stuff in an open source encryption and decryption unit that I didn't write myself. This code is in multiple (over a dozen different) newer versions of our Simple Upgrade Management SYSTEM (SUMS) products, which started as a Delphi 7 project. These many versions allow my customers to securely update firmware in many different microcontroller types, which is why I have to have many versions of these SUMS products.
AnsiString has worked fine in the Delphi 10.1 Berlin versions of both the Upgrade Manager program, which encrypts the hex file, and in the many versions of the bootloader program, that de-crypts the hex file and programs that into the microcontroller. Encryption is needed to protect my customers' Intellectual Property (=their firmware in the microcontroller) from theft.
I suspect that changing this uTeaSet module to use Unicode strings will require me to make new versions of every one of these SUMS products, which will cost a lot of time and therefore money.
I can certainly sympathize! You might want to look into what it uses for its encryption - maybe it uses some kind of standard algorithm that you can easily replace or augment. Or if it is open source and still supported, maybe someone has upgraded it to use Unicode strings already? Encryption has come a long way since Delphi 7.
Doing a quick search (and making a ton of assumptions, just going on uTea!) I'd guess this is a Delphi implementation of the Tiny Encryption Algorithm? There are a few implementations out there, some older using AnsiString, but some newer implementations as well.
Sorry to bother you on a weekend, but I am having a terrible time over here. I have tried to set up a very simple test project that contains a few TWebButtons and a TWebMemo, which is similar to a Repository project I have used over the years to work out tricky code. The project looks like this when running:
I was going to use this to try some of your suggestions, but even this simple WEB Core project is not working as I expected. I initialized WebMemo1.Lines in the Object Inspector to "Starting the program.." and then expected to be able to use the following methods to add more lines of text:
// Code to manage "Results" display
procedure TMainForm.AddToResults( nextString: String);
// Appends any diagnostic strings, arriving from HIDagent's OnDisplay event,
// to our ResultsMemo display
One of the most basic troubleshooting tips is to use the console.log function which works a bit like ShowMessage but you can use it to output things to the JavasScript console which is always available. Eg, in WebFormCreate, add something like:
console.log('App is running...');
Which is kind of the basic thing you're trying to do with the TWebMemo here anyway.
Here are a few things to keep in mind. Now, you're doing things a little differently than I did when I first started as I just set aside the VCL code I had and started with a blank page, copying the contents of functions and code snippets and that sort of thing that I needed, but not using the units directly as you're doing. This idea of migrating code more directly is a bit more challenging but understandable as you're trying to save time obviously by using what you've got.
Your interface isn't actually wired up to the underlying code. So for example, the button onCclick events aren't tied to the procedures you've defined. So that's job #1 - get the events set in the IDE so that, when you select a button in the IDE, it is mapped to the procedure in your code.
If you click on a button or other control in the IDE, the available events don't include your events. I just moved them from the "private" definition in the interface section to be just above it, and then they appeared and could be selected.
You're likely to run into this more often than I do with this overall approach, but the compiler will give you clues when your code isn't being used. After wiring up some of the interface, I was still left with these messages from the compiler. Not things critical to your test, but later on when they start showing up you'll certainly want to find out why.
[Hint] Unit1.pas(25): Private method "TMainForm.EnableUserControls" is never used
[Hint] Unit1.pas(27): Private method "TMainForm.FormClose" is never used
[Hint] Unit1.pas(28): Private method "TMainForm.FormDestroy" is never used
When uploading projects, you can leave out the TMSWeb, Win32, __history and __recovery folders and things will be much smaller. Kind of tedious depending on how you're creating your zip file but their contents are likely not going to be used anyway, so no point in including them. Makes the file much smaller. No big deal in this case but as your project grows this will become more of an issue.
Hope that gets you a little further along. Don't feel bad about any of this stuff. It is a completely different environment than a Delphi VCL app runs in, so there's going to be some learning along the way. And there are lots of different ways of approaching it. And porting code is going to be more challenging than starting from a blank slate, certainly. But just until you get the basics down, then all the rest of it will become immensely useful again. And waaay more fun
Yes, in a rush, I had pasted OnClick stuff to the Private section instead of the Published section. Those items were removed from OnClick when I compiled, but I didn't see that at the time. I have fixed that, and now my little re-usable test project works correctly.. Thanks again for your help!
I have gotten breakpoints to work in the Firefox "debugger" tab, as well.
I have sent another question to the help request about "trouble adding menu items" in which Ken Randall had suggested using TJSValueDynArray to make an equivalent of a variant record to fix some more compile errors. The compiler or linker cannot find either TJSValueDynArray or TJSValue. I need something to put in the "uses" clause. Any suggestions?
Sorry, I was referring to JSValue as the type. It isn't a unit, and it is usually a type that is covered by the default units anyway, you don't need to add anything new to your uses clause. For TJSValueDynArray, you do need to add Types to your uses clause for it to be found.
In this example, I think he was just showing that a typical table lookup function uses a variant as its second parameter to pass the different kinds of values needed by the columns that are passed as the first parameter. And to do that in TMS WEB Core you'd need to use one of these TJSValueDynArray variables instead of an actual Variant that you might normally use.
But that's just an example he's providing, where tblX is referring to some kind of generic table that has a lookup function. If you're not doing a lookup on a table, then this isn't all that useful. It just happens that this is a pretty common case where Variants get used in traditional database-oriented VCL apps.
Or maybe what he was suggesting was to use a TJSValueDynArray in your record and store the different values in that? I'm no expert on any of that kind of thing (this was the first time I've even heard of TJSValueDynArray!). Happy to help work through it though.
Maybe make a new post with the kinds of records you're working with and we can figure out a more optimal approach. Be sure to include the record definition (or the relevant bits or a comparable equivalent - don't need to post anything proprietary of course), as well as some examples of the code that you use to access them. So that a new record definition can be found that will work with the existing code that uses it, or simple replacements can be found to make it more of a search/replace kind of process for you.
Yeah, I suspect I'm gonna have to work out some ideas for this. I appreciate your willingness to help, so if I cannot find a way, I'll get back to you on this, maybe tomorrow, after I noodle on this awhile. I'm sure that whatever I come up with will be less efficient than a variant record, but code size is not important on the PC side program this is porting.
The microcontrollers that the PC communicates with have limited code size, but those do not need to be updated.
Yes, and if you think about how much RAM a browser takes up all its own, and then how much a typical page consumes, and so on, we're nowhere near the situation 15 years ago where extra bytes in a record were a potential concern. Even if you have tens of thousands of records. Looking at this page in the FireFox debugger for example suggests it is currently taking up 93.66 MB. And there's not really much going on here. I'd be surprised if you had a microcontroller that had that much code being passed to it!