Jump to content

David Schwartz

Members
  • Content Count

    1190
  • Joined

  • Last visited

  • Days Won

    24

Everything posted by David Schwartz

  1. David Schwartz

    Is anybody working with TMS WebCore non-visual libs?

    1) They're delivered as part of the WebCore release and they are not otherwise distinguished as to their origin or who to contact with questions. So I contacted the only obvious people to reach out to. What else would you suggest? 2) I got no reply from the first post, and eventually something from the second. I don't know why nobody replied to the first one, but I can't remember ever NOT getting a reply to support tickets sent to TMS -- if not from Bruno, then someone else. When I have problems with anything from TMS, I know I can count on getting an answer. I've had some really crazy issues come up over the years, and Bruno has always come through, even if it took a while. Even in cases I figured were hopeless, Bruno always showed up with an explanation, if not a remedy. That said, a guess was offered that, if it had been actually tested, would have shown it wasn't viable. These libraries were delivered with not one hint of documentation, tests, or demos. But Bruno did finally respond saying he contacted the pas2js people and they confirmed there was a problem in the translation, that it has been fixed, and they will issue an update in the next release. Yay Bruno! Regardless, without any other knowledge or information, I posted something here simply because I was curious if anybody else has used these libraries and was able to get them to work. This seems like a fair thing to do, especially if the folks who delivered them aren't able to help. I do appreciate the fact that somebody went to the trouble to translate these libraries and that they're more like "quick and dirty" code ports than actual products. If you have a tool that can do that with a few mouse clicks, why not? But even one simple test unit created to verify that the resulting code compiles and runs would have saved a lot of headaches in this case. I did spend most of a day trying to figure this out before reaching out to anybody. Maybe I'm the only person actually using these libraries. I don't know. Nobody else has raised their hand yet and said one way or the other.
  2. David Schwartz

    auto-generated REST APIs?

    Does anybody here have any experience using tools that auto-generate a REST API from a DB schema? Here are a couple I've found: https://github.com/o1lab/xmysql https://github.com/mevdschee/php-crud-api I'm curious about using something like this vs. a hand-rolled REST server. Obviously this is going to publish pretty much everything, delivering 1:1 mappings to the DB structure. It strikes me as best for simple DBs. But from what I've seen of examples of REST service designs, they often function a lot like views rather than just mirroring the DB's structure. Any thoughts?
  3. David Schwartz

    Delphi and Parallels for Mac

    I used Parallels for a while, then switched to VMWare Fusion, then to VirtualBox. TBH, I've had the fewest issues with VirtualBox.
  4. David Schwartz

    auto-generated REST APIs?

    I guess I should have been more specific in my question. What I was thinking was using this myself in situations when the DB needs are simple enough that going to the trouble of building a server-side app may not be warranted. I cannot imagine publishing this for outside use -- only for internal use. A good compromise would be if the generator could work with stored procs and/or views defined in the DB to extract specific filtered or aggregated data. Also, it makes sense to me as a means of switching from classic Client/Server to REST-based interfaces without having to change anything (unless stored procs and/or views are being used).
  5. David Schwartz

    looking for animated 3D lettering

    Someone gave me a bunch of PowerPoint slides that have a static background image and some fly-in text. They play a short music track over it, and record a video using Camtasia. That's ok for a few, but it begs to be automated. They make short videos that are delivered via a web page. My goal is to load the image, start the audio file playing, then fly-in the text, using TMS WebCore, inside of a web browser. The audio stops and that's it. Simple. I'm trying to make it so we can skip the whole process of setting up the PPT slides, the music, then recording each one in Camtasia. Instead, we'll either select a BG image, music track, and text randomly, or make a list of triples that will be used together. It's easy to load up a static image and trigger an MP3 to play, but how do I do the fly-in text? (What I'm referring to are the text animations you can do in PowerPoint where it slides, drops, flips around, spins, and other stuff.) While I think FMX may be able to do this directly, TMS WebCore probably requires a graphics lib that's VCL compatible. Can CSS do fly-ins? Also, we don't need hundreds of different fly-ins. It's just for some variety and eye-catching animation. A dozen would be fine.
  6. David Schwartz

    looking for animated 3D lettering

    No, but I just discovered that PowerPoint can now generate Animated GIFs! What does it take to show an Ani-GIF in a Delphi app?
  7. David Schwartz

    fun coding challenge

    Just for fun, I thought I'd post this here. I have four TMemos on a form into which users can enter some lines of text, usually not more than 5 lines, but that's just a guideline. Let's call them m1, m2, m3, and m4. There's a field where they can specify a "delimiter" like a space, comma, hyphen, underscore, ampersand, etc. Write a method that creates a list of strings in an output TMemo composed of all possible combinations of lines from each of the four TMemos left-to-right (1+2+3+4) with the "delimiter" inserted between each one. So you get something like rsltmemo.Add( m1.Lines[i]+delim+m2.Lines[j]+delim+m3.Lines[k]+delim+m4.Lines[n] ); where each Lines index is in the range [0..Lines.Count-1] for that memo. For me, the obvious approach was four nested loops. Then someone suggested, "Why not just have an [+Add] button that lets you add as many of these boxes [ie., input TMemos] as you want?" The challenge is to write a method to generate the output from some 'n' input TMemos in as few statements as possible? Right off the bat, I can think of at least four different ways to do it, and more if there are things in the VCL libs that might help that I'm not aware of. (I have a feeling a good functional programming lib would let you do it in just a few statements for an arbitrary number of input TMemos.)
  8. David Schwartz

    do any git tools work like this?

    Many folks here have seen the various missives I've posted over the past 6 months or so trying to deal with learning the weirdness of git (my perception). I still don't know if it's just how my workplace does things or if we're not using git as the designers envisioned, but I have not run into many folks who seem to deal with stuff the same way we do. One of the things that seems to be at the root of my issues is the disconnect between git and work activities. We have a ticket-based workflow where our Cust Svc people create work tickets based on customer needs and post them to a few different ticketing systems we support (including Jira). It's a very dynamic environment, and we can end up switching between different activities several times a day. It turns out that tracking git branches by naming them for the ticket numbers we're working on works well for our needs. The problem is, we can be on a meeting and questions will come up about different tickets and issues that I or others may be having, so I find myself switching from one ticket to another to another. Delphi doesn't know anything about tickets, nor does git or any other tool. But if I've been working in a git branch and make some changes to files in a folder for a given ticket, then I switch context, work can literally disappear if I change git branches without committing my work. Even worse, uncommitted work can inadvertently get attached to the wrong ticket / branch if I'm not really careful about what I'm committing when I do a context switch. In a nutshell, my work activities are highly interrupt-driven with lots of context switches throughout the day, so it's very easy for git to become out-of-sync with the work I need to focus on. I ended up building a tool that is designed around the notion of these "tickets". In most respects, a "ticket" is just a name with associated tasks, a client and one or more working folders. There's also a git branch named after it as well. So when I switch tickets in this "workbench", it does a full context switch for me: it pulls up notes, lists, related folders, and changes the git branch. One thing that's interesting about it is that if I try to switch to another ticket and git detects a conflict, it won't switch branches. I have to go in and do a commit or a stash, which is actually a very quick operation that's built into the workbench. This alone has saved my butt several times, because I'll usually either forget to change branches, or I'll not want to deal with the commit because it's just an interrupt. Delphi doesn't care, but once in a while I'll switch tickets with a project open in Delphi and when I go back to Delphi it will alert me that the underlying file(s) have changed. This is the problem that has caused us so much grief in the past where files get overwritten without our real understanding what was going on. (Delphi simply reflects the underlying file changes that switching branches often entails.) Anyway, I've seen lots of GUI tools for git, but they're all focused around git and git's workflow. We don't really deal with git, or even care about git's workflow at work. We deal with things the customers want, and these "wants" are enshrined in what we call "tickets". Our workflow focuses on tickets. Git ends up being more of an annoyance than anything else, like a pet that's always jumping into your lap when you're trying to do something else, and they hit the keyboard with their paw and wreak havoc while you're trying to put your coffee down without spilling it all over the place. The workbench I've created bridges the gap between having git branches being out-of-sync with work activities, and it works incredibly well. It has a bunch of git functions built-in that make it super easy to keep everything straight. I'm curious if anybody is aware of any general purpose tools that might do this. If not, I may be able to generalize this in places so it would be more broadly accessible to others. (FWIW, it is not integrated into any ticketing systems we have -- they don't let us do that. So "tickets" in this context are simply what we use to name working contexts. There are a few things highly specific to our environment that could probably be made configurable, but for the most part, it's quite generic.)
  9. David Schwartz

    do any git tools work like this?

    Hmmmm ... I'm not sure what I'm missing. There are two devs who have been using git for many years, but they're web devs. They can't wrap their heads around having a dozen or more files in our source tree that are just "compiler artifacts" (eg., dcu and other similar files) that don't need to be maanged by git. They think our whole set up is extremely convoluted. I didn't set up anything we're working with. It was done by people 10+ years ago who are long gone. There's no documentation, and a variety of opinions about how things ought to work. Nobody is really sure, so we experiment and tend to follow the path of least resistance. I feel lucky when things work the way I expect. 🙂
  10. I found this library: https://www.syncovery.com/tgputtylib/ I'm guessing it's built with D10.3 while I'm using D10.2 I extracted the entire file tree to a folder and rebuilt the components and libs, and set up the search paths. (I moved the output into the same file tree rather than using the default.) I can run the VCL demo just fine, but the VCL Component demo blows up with an "External Exception". Strangely, my app with NO component blows up with the same error. I copied the code to init the lib from the VCL demo (non-component) and it blows up when it's initializing one of the DLLs. This demo even adds tgputtylib.pas and tgputtysftp.pas to the project, so I did that as well. That app works, mine blows up. There's exactly one dll and one bpl file on my system, and I did a BUILD on EVERYTHING before running it. Whatever is causing my app to blow up seems to be causing the same error when the component inits the DLL as well. All I'm trying to do is write a bit of code that needs to upload a file to a server using the SFTP protocol, poll every minute waiting for four output files to appear, then download them. These need to be called in discrete steps: Upload, wait for results, download. I've tried four different libs and approaches now, and every one has quirks that keep them from working, or they're just too complicated to figure out. I don't use a lot of DLLs so I'm quite baffled how one app would happily init the DLL while the other that was more-or-less cloned from the first blows up during the DLL init step. Suggestions welcome (including useful code samples that I could try).
  11. David Schwartz

    strange problem with psftp lib

    Well, I put the lime in the coconut and ... oh ... I mean ... I put the DLL in the folder with the EXE and ... it worked. I thought I'd done that earlier, but it somehow snuck into the folder next door.
  12. David Schwartz

    compiler setting issue?

    Here's some code in a unit that compiles without error in a demo project (DX10.2): function TVCLSFTPClientDemoForm.ListingCallback(const names: Pfxp_names): Boolean; var StartRow,i:Integer; begin StartRow:=sgRemoteFiles.RowCount; sgRemoteFiles.RowCount:=StartRow+names.nnames; for i:=0 to names.nnames-1 do begin sgRemoteFiles.Cells[0,StartRow+i]:=Utf8ToString(names.names[i].filename); sgRemoteFiles.Cells[1,StartRow+i]:=DateTimeToStr(TTimeZone.Local.ToLocalTime(UnixToDateTime(names.names[i].attrs.mtime))); if names.names[i].attrs.permissions and $F000 = $4000 then sgRemoteFiles.Cells[2,StartRow+i]:='<dir>' else sgRemoteFiles.Cells[2,StartRow+i]:=IntToStr(names.names[i].attrs.size); end; When I paste this same code into another project that I created from scratch, I get errors saying "names.names is not an array" and it won't accept the [ i ] ]] subscript reference (square brackets apparently control italics). In fact, it's an array of pointers being returned from a DLL written in C/C++ where instead of using a subscript, it's probably using *p++ to iterate through the list. Here's how the data structures are defined: fxp_attrs=record flags:TUnsignedLong; size: UInt64; uid,gid, permissions, atime,mtime:TUnsignedLong; end; Pfxp_attrs=^fxp_attrs; fxp_name=record filename,longname:PAnsiChar; attrs:fxp_attrs; end; Pfxp_name=^fxp_name; Tfxp_name_array=array[0..20000000] of fxp_name; Pfxp_name_array=^Tfxp_name_array; fxp_names=record nnames:Integer; names:Pfxp_name; end; Pfxp_names=^fxp_names; I can't help but think this is probably a compiler flag somewhere. Any ideas?
  13. David Schwartz

    compiler setting issue?

    Well, that's at the top of the 2 files with this code in it, so it looks like the culprit. I'll give it a try. Yup, that solved it. Thanks!
  14. David Schwartz

    strange problem with psftp lib

    I copied the form from the VCL demo that works into the folder with my code, added a button to pass the PSFTP object to my form instead of creating it, then tried to run it. When the other form tried to initialize the DLL, it blew up in the same place. Is there supposed to be some handshaking between the client and the server when a connection is set up? I vaguely recall seeing a popup window saying the client hasn't seen this server before and asks if it's ok, and I click Yes. That thing isn't happening on my app, and it's not happening on the demo app when I moved it either. I read there are a couple of libs that let you tell them to simply "accept" this thing. I'm not sure if this lib does that or not.
  15. David Schwartz

    Reading fields with different lenghts

    use a series of Copy statements specifying the start col and field length
  16. David Schwartz

    LiveBindings question

    I have not used LiveBindings hardly at all, but I was wondering if they allow you to cross form boundaries? Eg., from one form to a ShowModal form it displays for data entry / editing
  17. David Schwartz

    What is the best way to split off a new project?

    No, they're not that independent. I think I mentioned they do refer to some data vars in the main form as well as a few screen elements (although those are usually hidden inside of methods).
  18. David Schwartz

    Listview control with filtering like File Explorer

    I'm curious as well. There are some Windows-specific features that get merged into Delphi almost as soon as they show up in the OS, while others like these never seem to make it. They're still using an ancient version of the DLL interface that wraps the RichEdit control. If you want access to the latest features, you need to resort to API calls and callbacks. Why should we have to buy 3rd-party controls to get access to stuff that's in Windows DLLs that hasn't been updated in years? This is another argument in favor of open-sourcing the VCL -- so access to new features in Windows isn't competing for resources needed to add more features to a rarely used library included in the Enterprise or Architect Edition of the product. Delphi keeps growing outward, and very little effort has ever been expended to update the inner-most features of controls, except stuff that's in the base objects that affects almost everything. Keeping current with updates to Windows common controls has never been very high on any new release priority list ever.
  19. David Schwartz

    What is the best way to split off a new project?

    OT: I have an app that has some tabbed notebooks (pagecontrols) that have a collection of related things on them. Some have their own tabbed notebooks. They are more or less isolated functions and could probably be moved into TFrames or even embedded TForms. But they're part of the main form's overall logic. I look at those chunks of related functions in the source code, say 5 to 15 methods, and wonder if I should move them into a separate unit. I'm not sure they really belong in a separate class, though. I've heard that in C# it's possible to put the implementations of methods of a common class into a separate unit and that the compiler will merge all such units into one at compile time. These methods are part of the main form's object, so I can't easily split them out into another unit. I really dislike having huge main units because the Delphi gods don't think many Delphi users would find it helpful to be able to do the same thing C# allows and move chunks of related code into smaller independent units that get merged in at compile time. Is there something you do by any chance to facilitate this sort of code disbursement?
  20. Our system does not capture outer-most exceptions, and throws these annoying error messages that are rather hard to decipher on their own. We've been building up a catalog of them, and they fit a collection of patterns. We'd like to have a form with a field where someone can paste in an error or exception message that shows up in an email, click a button, and it would bring up anything in the database that matches this message pattern and any associated comments. The first cut matches a Format pattern based on a collection of responses rather than a collection of these from the source code. (maybe we could go through and manually reconstruct RegEx patterns for these as there are only around 50 of them.) So, for example, there may be this somewhere in a source file: Raise Exception.Create( Format( '%s - Exception %s - something happened in xyz; %s - %d', [....] ) ); If the message in question looks like it fits this "template", then narrow down the search field to those we have documented that also match this template. The second cut looks at specific data values -- so, for example, the 'xyz' and the word following it provided by "%s" or the following "%d" 'xyz' might be a table name or process, and the following field identifies a column name and value that it choked on. In this case, the 'xyz' is the discriminant, while the next to parameters are just whatever was there that it choked on that time. Eg, 'xyz' = ADDRESS TABLE and the following might be "ZIP_CODE = '' is not a valid number" the underlying problem here is that we've got a bunch of StrToInt(...) calls and the developers chose them over StrToIntDef(...) because there may not be a realistic default value to supply. Usually these errors indicate one of two things: (1) a required field in the data file was left empty; or (2) there's an extra or missing comma (field-delim), or sometimes an extra or missing quote. (This is typically referring to a CSV file being imported.) We want something that will search the list of exemplars (that require as little pre-processing as possible) and return any notes and explanations associated with any matches it finds. I was thinking of perhaps adapting a chat bot for this purpose. Does anybody have any experience building something like this that could offer any insights?
  21. David Schwartz

    how to classify and match error message patterns?

    not sure what that is exactly, but I certainly didn't need to post here to learn the most obvious brute-force approach to solving this. Just to be clear, I know how to go through a list of exemplars and write a regex expression to recognize each one. I'm looking for another solution. If anything, I'd write something to parse the existing exemplars and construct regex expressions from them. I do not like brute-force approaches to problems that require things to be manually updated every time something changes. If I did, I wouldn't waste my time with object-oriented programming; I'd probably stick with assembly language. I don't think anybody noticed my mention of adapting a chat bot for this. Chat bots are designed for parsing similar stuff, from what I can tell. I was thinking maybe someone here has some experience with them and could comment. I'd also like to hear from folks who have experience with writing parsers and might know of similar problems to look at.
  22. David Schwartz

    how to classify and match error message patterns?

    It sounds like you're suggesting we go back into the code, track down every place it generates these errors, and change the code. That is not an option. We get what we get -- error messages sent to a logfile and put into a note that's sent via email to a group list. And what we get is a bunch of error messages that look like this: Error in ChildDone, C:\Loader\bdm001_44117.6013302546\bdm001_checks_imp.exe: Import error - CUSTOM CODE ERROR: (PostDocumentExtract) Requested image not found - 261101.png We've collected nearly 150 exemplars like this, about half of which have detailed explanations attached to them so far. They're just damned hard to sift through visually, and some are very similar yet distinct. If it was easier to map a given error to an exemplar, our list would be far more useful to people. I want to be able to paste messages we get like these into an edit box and have them parsed sufficiently to match a pattern, then search through the collection of messages and find any that match the pattern and have additional details added below. There's stuff here that's relevant literally (eg, "bdm001_checks_imp.exe"), some that's relevant in a meta-data sense (eg., the 261101.png is "<number>.png") and some that's totally irrelevant (eg., "C:\Loader\bdm001_44117....\" up to the next bdm001_). I'm looking for insights on how to do that.
  23. David Schwartz

    general question about embedding docs in an app

    I'm using a pagecontrol to add tabs with TMemos that I go into at design time and add text that gives tips on different aspects of the program. I'm not aware of any controls that offer fairly full edit features at design time (eg., a full rich-edit editor), but the trade-off is you have some baggage with all of the text stuffed into the EXE. (Given all the other crap the compiler puts in, 10k of self-doc text isn't even a blip.) What would be more useful would be a tab with a TWebBrowser on it that goes to an embedded server that runs a wiki or wordpress installation, that could be used any time to access or update the docs, including adding screenshots and whatnot. The point is to have something that travels with the program and can be updated from within it, rather than the usual help files that usually require a separate app that's usually restricted to the dev organization. Ideally, that wiki or WP site would be on a real server somewhere, but we have these crazy restrictions for anything that goes onto a web server, and it practically takes approval from Executive Staff to authorize it. But an embedded web server and a small sqllite db that can be copied as a single file would not be a problem. Are there any VCL components that would enable something like this? (I'm not looking for just, say, some HTML components.)
  24. David Schwartz

    general question about embedding docs in an app

    Thanks, I have TRichView in my own personal library, but the company doesn't. It is an excellent product.
  25. David Schwartz

    GUI automation tool for Firemonkey apps ?

    Tangential story here: I started working at this new company earlier this year. My first programming task, as it were, was to move this app from a WinXP VM to a Win10 VM. That's really all it was supposed to be. It seemed to work fine in XP but kept randomly failing in Win10. I guess several people had "researched" it for a while and had concluded there were certain problems, and they gave me a bunch of directions and things to test. Regardless, they thought it should only take a couple of days but may need a little tweaking in the app that was controlling things. So I started to dig in. First discovery: they were using a Windows app -- Version 1.0 -- that ran OCR on a big batch of forms that were scanned in and delivered to us as PDF files. This was a batch-mode process, so they had a control program that stuffed keystrokes and mouse events into the Windows message queue to control the app. I guess they had a lot of variance in the timing because everything had a 5-sec delay. Except the OCR function itself, which had a 45-second window. It frequently timed-out. Second discovery: all of that "research" people did was useless. It turns out, they were making observations on a folder thinking it contained files that were being scanned and then imported into the system. Turns out the stuff in this folder was more of a "discard" pile of slag left over as part of the OCR process. The fact that the app kept crashing at the same apparent point made it look like it was choking on one particular thing, which appeared to be some failure to rename a file. Later on, I figured out the failure was because it failed to rename MOST of the files, whereas the last one they thought was the problem was actually done correctly. An early thought we had was maybe this old app had problems running in Win10, so we contacted the company to buy an upgrade. The company has a page with a "Buy Now" button, but it goes to a form with a bunch of questions that are sent to a marketing guy who was trying to determine what the optimum solution might be. We just wanted the latest version of the same app, but they refused to sell it to us. We didn't say exactly how we were using it, and I suspect our use violated their license anyway, which some others at the company also suspected. Instead, the marketing guy was trying to sell us a hosted version that we estimated would cost us about $10k/mo. Never mind that it wasn't HIPAA or PCI compliant, which we required. Their self-hosted solution was around $75k from what I could tell. The only thing I could see for sure was that the old app wasn't 100% reliable running in the Win10 environment; it def. had problems. So I started looking around for another OCR solution. I found one from a British chap that cost under $100 and was a Delphi library (not a DLL) that had no license restrictions that might affect our use. I hooked it up, did some testing, and it ran amazingly fast. When I cropped part of the page to restrict the scanning to the part with data we wanted, it went even faster. The original solution took 6-8 hours to process most batches of data we got, while this one completes the same input data in 20-40 minutes. The other thing I discovered about the original code was that the error handling was worthless. (I've found that in a lot of our code now.) I got it working and discovered a TON of errors were happening AFTER the OCR process ran, and that implied about 25% of the data it scanned was not valid or did not correlate with known data as it should have. I guess it was getting a lot of false hits because it was scanning the entire page, which often had weird artifacts that matched things we were looking for, only they were in the wrong place on the page, so the neighboring data it captured was wrong or missing. I rewrote the whole damn thing in a way that allowed us to switch between the two OCR engines. The new library worked a whole lot better. The older one still worked; it was far more robust and didn't fail as often, but it still took hours vs. minutes. Management wasn't happy because it took me way longer than they expected. I was surprised they weren't concerned about the opaqueness of errors, poor scanning quality, or the overall execution time. Or even the fact that all of their initial assessments were 100% off-base. Oddly, someone who heard about how the original code worked expressed interest in maybe adapting it to do GUI-based testing. The mere thought of using the method they used here to drive this OCR app, but for more generalized testing, just made me shudder. Most of this software does not trap run-time exceptions, so it just terminates with useless messages like: "error reading item(0); attempt to read from address 00000026", or "error in numeric conversion: '' is not a valid number". This is after consuming tens of thousands of input records. Their solution: just step through it with the debugger. In 99% of the cases, it's bad input data.
×