Jump to content

Gary Mugford

Members
  • Content Count

    55
  • Joined

  • Last visited

Everything posted by Gary Mugford

  1. First of all, kudos to all the folks who participate in making GExperts. It is all appreciated. And in this particular case, I guess Robert Wachtel gets a big share. Thanks. Now, I THINK the reason for the expert is that people get busy working on a form and at some point, the compiled application won't do something particular, like say emptying a table, because it's still active in the IDE. I'm running head on into that nightmare right now. The Component Property Replace expert would save my mental fugues if it was JUST a little more particular about what it chooses to switch and what it doesn't. I have a BIG project, and it's an OLD project done in D7. There are a couple of data modules, one BIG central calling form and a nightmarish number of sub-forms. All of this grew organically and is out of control. A replacement is underway, but it's nowhere near usable yet. So, I'm stuck updating the old app. I'm working on a form that centres around a central database ON THE SUB-FORM that a number of reports run off of. I change things in any of the form's report objects and it auto-starts the database in question which I later need to deactivate before compiling. Something I do about HALF the time. Getting old and stupid. I would very much like this expert to replace my brain and do what I forget ... set the database.active to false JUST ON THIS FORM before compiling. Which the expert will be happy to do. But it also will reset the data modules and the big form, the latter one I expected from the fact it is open in the IDE, the former two, the data modules, somewhat surprisingly. There is a setting that allows you to limit the resetting to just the forms open in the editor. I sort of have to have the main form up all the time. I COULD try going without it just for this focused (or lack of focused) programming frenzy with the sub-form in question, but it would cause other issues. So, I make the following suggestion: Please have the expert ONLY apply to the SINGLE ACTIVE File TAB in the IDE's editor. Alternatively, the open files in the editor (which should exclude the data modules in MY working example because they don't have an actual tab in the editor). That would let me make the decision to temporarily shut down the main form to concentrate on the sub-form. The best of all worlds would be a radio box that allows: All files in project All open files in editor Just open file TAB in the editor Maybe reverse the three based on left-side/Top-side DEFAULT bias for picking since it's the small end of the working group numbers. Lastly, and this is probably the fly in my ointment ... I use Castalia as my editor. That MIGHT be why the data modules get included in my run of the expert. Or would, if I turned it loose to actually protect me against the ONE thing, while causing me to go back and but in the code to turn on databases on Form Creation for all the affected switch offs. A daunting task and why I am not actually USING the expert currently. Second lastly, a different approach, which I think is impossible ... letting me cite Form and component as a direct target. I'm actually doing this for ONE annoyance currently. Say I could put in TWorkingForm.TTable and have THAT set to false on compile FIXES ALL MY PROBLEMS and it doesn't create the possibility of mistakes spreading if I pick the wrong choice in my hypothetical radio box above. Regardless of whether this spurs anybody into their own programming frenzy, just want to repeat how much appreciation GExpers has from me. Thanks.
  2. Gary Mugford

    Slight Refinement to Component Property Replace

    Dummzeuch, Thanks for getting back to me. The reproducible answer would be, by necessity, a small project and the answer would inevitably be, have all database connections start with being off (perhaps through the expert in question) and then start them at run-time according to need. That way, when working with ReportBuilder on a single form at any given moment, you can ignore the fact that RB ACTIVATES the datasource while working on it within the IDE. IF you forget to deactivate the datasource before compiling, then come runtime testing, it will hit for example, table.emptytable, the program will throw and error, citing that the table is busy, Again, if you are starting over and (in good programming form) starting up the databases at run time in the code, this is the obvious situation the expert is for. MY Problem is that this is a 30 year old program that wasn't designed all that well at the beginning and only got worse as kludges and new features were added willy-nilly. I have, over hundreds of forms, and the two datamodules, several hundreds of database connections (I think a shade more than 400 at last count). Some are inactive. MOST aren't. They come up ready to go without me writing any lines of code. The expert DOES say it will only affect the active files in the editor, which in my case includes the BIG central form, with around 80 active databases on it .... yes, I can read the comments to be written already and acknowledge, in advance, their correctness ... as well as two data modules with about 200 connections, mostly active in the dLookUp module and mostly in active in the dData module. The expert, despite neither datamodule being in the editor at the time, indicated it would reset all connections in them, as well as the big central form and the one form I was working on. I needed it to be on the form I was working on ONLY. I think my narrow niche need for work on this is beyond making a request official. It's not worth other programmer's valuable time. Sigh. I was hoping the change would be a minor effort. Since it's not your expert, I understand what I am asking for. So, I will have to change things around just a little bit. I've lowered the top edge of the IDE and overtop of the button that I click to compile, I have placed a graphic telling me to DEACTIVATE the CBOX.DB. Crude, but it seems to be working. Again, thanks for all you do for the community. GM
  3. Gary Mugford

    Combining several applications into one

    Actually, I'm unfortunately going to have to agree with Mr. Heffernan. The end goal is a working umbrella process, it's true. BUT the end goal is also to have one cohesive program to run against Delphi Parser with a capped licence of 1M lines of code. So, I'm trying to pare down everything, no duplication, no sub-folders. Just code to update via Parser so as to change Database backbones. The idea of calling exe's would BE a solution if there was no next step. But there is. At that, they have the umbrella already ... the Windows desktop, in the form of LOTS of icons. Well, not lots. Each user gets icons for sub-applications that are pertinent to that user. My problem right now is that I have apparently wasted my time collecting all the code into one great-big folder and 74 sub-folders with subfolders and subfolders etc. That action was premature. I was hoping to speed things along, but the opposite has happened. The issue is that in ADDING units that weren't in the settings as search path entries LIKE my own home-grown utility libraries, they hard-coded PART of the paths in the DPR's uses unit. Now, I'm DISCARDING the DPR, but there's something in the DNA of the program that when I bring it up to rename the form, planning to save this copy of the form PAS file into a different name, something goes astray every time. It MIGHT have something to do with AJC Active Backup maybe getting confused given the file name no longer tracks back to the last version in it's database. Don't think so, but I'm throwing mud against the wall looking for a hidden message. Not everything, Maybe one out of four or five, but then the time with that one takes FOREVER to get done. Also, any mini-app with sub-forms takes two or three times the time of a single form, but that's to be expected. As I asked in the OP, I was looking for pitfalls. And I've found them. For future readers similarly run afoul of their own design, I hope reading this in advance of trying what I'm doing will help, although the better advice is ... Don't Screw It Up In The First Place.
  4. I have an archaic programming creation structure. For every project I create a folder. Inside that folder, a sub-folder called data and a sub-folder called proj. Within the proj folder, the application's main form is always called frmMain, saved to a PAS file called fMain. The project file is named after whatever I'm calling the program. Usually a short name rather than a full flowered name. i.e. ManifestMgr that runs windowtitle-wise as Manifest Manager version 5. Or somesuch thing. Each sub-form obviously runs separately but many will have a uses FrmMain in the clause. There are separate utility files that I use across all of my programming, so uses uGlobals, UGProcs and ESBDates are very common. The development folders are spread across four different drives. I INITIALLY thought to develop using a drive per group, but got sloppy and now any program can be anywhere, although the central utility libraries are with the Delphi install on drive E. What I want to do now, is to take a selection of those programs and combine them into one. There are three different versions of Delphi involved. My plan is to go through each program and change the FrmMain structure into something more applicable ... FrmMainEncryptedPasswordGenerator, for example. Which means going through all forms on the given example and changing FrmMain to FrmMainEncryptedPasswordGenerator, fMain in uses clauses to fMainEncryptedPasswordGenerator (or more likely, fPWGen). Having done that, I intend to glue the full contents of the folder to the one folder's contents that I intend to be the master program and set up a menu item in it to call on the file FrmMainEncryptedPasswordGenerator as a new sub-form. I worry that each of the new now-sub forms rather than standalone VCL projects, will have issues with things like auto-create and the such. I am not an accomplished programmer. I slog through things. I have never used pointers. Rarely used classes. Don't think there's an actionlist in the lot. I DO use third-party libraries, but they will call and use whatever tricks they have regardless of the new order in the universe. So, here's the question ... Anything I should be aware of in my stated course of action?? Beyond the finished product needing to be upgraded to the most current Delphi version of the three. I just want to know if the slow-and-steady process of changing the main form's name to something unique throughout the project and then gluing it into the central calling app, is a reasonable approach. Or might there be a better, faster, less-labour intensive way? Thanks for taking the time to read this and answers are always appreciated.
  5. Gary Mugford

    Combining several applications into one

    Frost, The renaming is not quite as easy as I thought it might be. I wanted to go in and edit the DFM and the PAS files and replace FrmMain with FrmMainActivityReportToolset in the copy I had made of FMain.Pas renamed to FMainActivityReportToolset.Pas/DFM. Then, I used the search and replace to find frmMain with the longer monicker. But I'm getting a lot of errors when calling up the form from the umbrella. The DPR file in the sub-folder might be involved somehow. So I'm going to work on that theory for the next few hours and then cutaway to watch the Clippers Raptors game. Back at it come midnight. Thanks for suggestion. GM
  6. Gary Mugford

    Combining several applications into one

    Rollo, GIT and whatever CI is are beyond my skillset. I'm just a slogger working through it, one app at a time. Problem is, it's one app every six hours at the rate I'm going. And year end is 80 days away. Seventy if I want to try things out first. Which doesn't leave much time for basketball on the TV and things like eating, sleeping and going to see the doctors. Sigh. Deadline pressure is good, if it doesn't kill you first. [G] GM
  7. Gary Mugford

    Combining several applications into one

    AE, Actually, there's a ground-up rewrite using a wholly customizable user interface that I was in the middle of when the breaking of BDE by the Microsoft Windows Update Fall 2017 made continuing to use the app, which dates back to DOS days as a Paradox app and went Windows in the late nineties with Delphi 1, untenable. So, it's past 30 years old and nearer 35 than not. What I think of Microsoft is not allowed to be printed here, I think. In order to survive until I can get the new software up and running, the plan became to get the app and ALL the satellite apps together and use Delphi Parser (a SHOUTout here for the amazing customer support) to do the backbone switch for me. There's also a gazillion instances of components from companies no longer in business. They have to be replaced along the way too. And I was shocked and dismayed to find I hadn't produced XE7 for my OWN components (merely extensions of existing components with more properties set). When I wrote ComponentKing to find the mish-mashes between D7 and XE7, it found the expected ones missing in XE7 like the long-cherished, but forgotten ABC components from Australia. At least I know what has to be replaced and have a Rosetta Stone of what goes where (technically, what gets replaced by what and WHAT I have to do post swap). And ComponentKing did give me a list of units to un-use via Parser or Replace. So, I've got a decent start. I never used things that trigger spasms from unicode. Replace will do the string/ansistring swap and the assorted cousins. BUT the whole shebang has to be ready for Parser to do the backbone swap and for me to have the app working lickety split. I've never had a single day of parallel testing and the longest beta test on record was one day. I'm expected to be functionally perfect (acknowledging I might not catch EVERYTHING ... until day two). I would follow your advice in other circumstances. But I agree with it one hundred percent. Thanks, GM
  8. Gary Mugford

    Combining several applications into one

    Lars, Rollo and Frost, Appreciate your comments in toto. Unfortunately, I wasn't clear. ALL of these applications, save one in Delphi 2010 and a half-dozen in XE7 are in Delphi 7. In creating the umbrella app, I want ALL the source code of the umbrella app and the 74 independent apps in ONE folder. There's a reason for this, I need to bring them all together for Delphi Parser to help change the database backbone. The end result needs to be a case of all the software working with the new backbone,, the apps being menu items in the umbrella main app. It's ballpark three quarters of a million lines of code. And it has to be ONE APPLICATION, ONE FOLDER. Oh, and working in Delphi 7 with an eye towards the lot being transitioned to XE7. I LOVE the idea of frames and looked at them. But I didn't use them, preferring composite components. Bad decision. But I've been in the 'Get it to work' business for a long time, once releasing more than 250 updates in a single year (and that was one a day) back in the early days. My employer suffered from the dual scourges of not telling me enough and then having an active imagination when seeing what was possible. But those days of turning in updates two days out of three are long gone. The kludged together main program and all the satellite apps now need merging. Faster the better. I'm stuck on something I managed to change into non-usability back in 2017 but left it like that since the 2015 version of the software worked. Now, I NEED to fix what I broke. But once I get past that, I THINK I have the routine of work down pat. But that leaves me thinking I'm missing something. It's worrisome. While not being able to immediately take advantage of your advice, it's in the bank for moving forward. Thanks!
  9. Gary Mugford

    ANN: StyleControls VCL v. 4.53 just released!

    Tim, And then the drones set it back. Or to something worse. And they obsess over themes. PLUS, Teamviewer (I'm housebound and haven't been to the office in eight years and counting), which I use for remote access, takes the colour out to speed communications and I have to take that option due to the small pipe at my main customer. I'm hoping styleControls overrides that for me, while maintaining the rest of the windows I'm NOT interested in being useless white. Ack! More whining. If they give me the thumbs up that I can pile a NextSuite TabControl notebook on top of a themed form with nifty title bar and then on the pages of the notebook I can use MY choice of components and they'll get themed, then I have my hot plastic STARING at me from a shelf on my desk. GM
  10. Gary Mugford

    ANN: StyleControls VCL v. 4.53 just released!

    Almediadev Support, Thanks for the reply. I DID look at your third party list as I mentioned in my comment and saw a large proportion of my libraries there, but not all. (By the way, the link included above doesn't lead anywhere). That said, the question remains, what does the presence of say a NextSuite tabbed notebook look like on a page of your otherwise themed form WITH controls that are themed? Does the parentage of it being the NextSuite control mean the theming doesn't apply, or do the controls theme regardless of ownership? As for the dialogs, I'm curious, but they are not a show stopper for me. In fact, having dialogs that STAND OUT from the background would be something good rather than not good. Frankly, the overall look isn't something I'm overly sensitive to. What I AM sensitive to is that the default Windows 10 'theme' is horrible. The white window title bar header is beyond useless against a sea of windows with white from edge to edge. In the old days, I had control of things. A simple GREEN for active window and RED for inactive windows made screen recognition easy. But through aero and glass and all that, Windows became something that almost beggared being run full screen. Which I hate as I remote in to see all my apps being run full-screen. I run multiple monitors with maybe a half-dozen windows open at any given time, usually more, and some of them over-lapping. Title bars that instantly show me active status help immensely. What I particularly like about your StyleControls is control over the title bar. One last question if I may. I have a project I'm updating from D7 to XE7. On the form, I have a lot of controls where I've manually set the colour, the font specs and various other visual bits (transparency, alignment, etc.) Now I have the form ready for the addition of your StyleControl, which I assume is a non-visual control. On it, I pick one of your themes. What happens next? Do all the defaults I have NOT adjusted switch to the theme, but the ones I manually set stay the same? Or does everything switch over? e.g. If I have the font.color set to clNavyBlue, but the theme I've set it all to is orange and black, does the font colour still stay blue or does it switch to black (or orange) in my example? Does the theming over-ride Transparent? Thanks, GM
  11. Gary Mugford

    ANN: StyleControls VCL v. 4.53 just released!

    I've looked at your product several times over the years. But being mostly D7 programming into a Windows 7 environment, I let the urge pass. NOW, I'm stuck re-doing a project that is the hodge-podge result of about 35 years of programming starting in the era of DOS and Paradox 1.11i. We now face the Win 10 apocalypse that broke BDE almost completely. The result, well now I am looking at homogenizing things moving forward. I like the TMS and JV sets of components and I have a variety of other ones that I dip into (DevExpress, Woll2Woll, etc) as the case may be. But what I don't see on your list of compatible component sets are NextSuite and ESB controls. There are others that are more single use than most. What is the ... compatibility with what to you are third-party components, while vitally necessary to me?? If they aren't compatible and WON'T be moving forward, what is their look on one of your themed forms?? And dialogs. I use the JSDialog's with D7 and then their more-or-less descendent NG dialog pack from LMD in DXE7. Do they stand out (which I'm NOT against), or get themed too?? I'm aware you have your own controls. But I KNOW the options and coding of the others. The learning curve and versatility vs. the Known. It's a big thing. The pricing is quite reasonable. The time might not be. So, you see I'm fence-sitting willing to teeter or totter depending on what you say. Thanks for taking the time. GM
  12. Gary Mugford

    Find all your components

    You really should investigate Peganza Software's Pascal Analyzer. The Lite version is an easy test and is free. Look at the Controls report to give yourself a flavour for PAL. Now, the fact is, that the full version is full of goodies. For example, it has the PalCMD.exe program to use as a potential command-line interface to the full reports. You want to look at Uses and Control Index. Those are the money makers. Combine PalCMD with a program like SWEEP.exe that lets you iterate through a folder and all it's sub-folders running a command line. For example, I use the following lines to explode a bunch of 7Zip files in their respective folders and then delete the 7Zip itself. Not exactly the toughest of high-level programming but it works ... G: E:\apps\Utilities\Sweep.exe E:\apps\Utilities\7zip\7z.exe x *.7z E:\apps\Utilities\Sweep.exe del *.7z Not every folder HAS any 7Zip files. But when sweep finds them, and it will, it explodes them. The next pass then deletes the 7Zip files. Now, switch the concept to running a PalCMD command-line and you can generate all PAP reports of what it finds. Then you can sweep all those PAP files into one folder. (I use AutoHotKey instead, but sweep CAN do the job with a copy command). Then, you write your utility to PARSE the reports one-by-one and there you have your Master Concordance. I wish I could offer help with your HELP.zip file, but unfortunately, I don't have YOUR version of RAD. I've spent part of today trying to genericize ComponentKing to READ in REG export files and show the concordance between two versions, dubbed OLD and NEW. Not QUITE getting it all right. But it's because I've played around a little TOOO much trying to fine-tune the output to get rid of extraneous information, such as the TcomponentBased. prefix for what I call the source in XE7. Unlike the Palette key in D7, where the source can actually be listed, the Mapping key in XE7 doesn't directly list the source. It's more SOURCE TYPE, instead. But I can live with that, since the whole purpose of the exercise for me is to help develop better ReFind change command templates. If I get something together that's worth others looking at it and using it as is, I'll post ComponentKing here. It's not pretty, but it does what I need it to do. Your need for a master concordance is different than mine. Hope PAL and Sweep or variants of each help you out.
  13. Gary Mugford

    Find all your components

    I'm hoping this becomes everything you want. I make use of Pascal Analyzer Lite to help me compile master lists. Still, that's a little Project-by-Project centric. I make use of Xplorer2 as a file manager and that lets me actually quickly find and list all the pas/dfm's on my ide drive and copy them to one master folder. I then let PAL loose on the accumulated lot. That helps to a certain extent. Oddly enough, I did spend time on the weekend creating an app to list all the components for D7 and DXE7 that I have installed. I have a version that worked in the Delphi's up to 7, mining the [HKEY_CURRENT_USER\Software\Borland\Delphi\7.0\Palette] for all the tabs and their contents. * Replace the 7.0 with each preceding version number. But looking for the Palette value with XE7 was useless. The compilation keys were at [HKEY_CURRENT_USER\Software\Embarcadero\BDS\15.0\ToolForm\Mapping]. There were other issues. XE7 separated items via commas, D7 and before by semi-colons when breaking the key value into stringlists. And the source library prefixes are considerably lengthier in XE7. For example, TMS' AdvStringGrid is TComponentBased.Vcl.Controls.TControl.TAdvStringGrid in XE7 but only AdvGrid.TAdvStringGrid in D7. I basically gathered each version's components into a master database that had fields for CompName A40 InD7 Bool InXE7 Bool Pg A40 D7Lib A50 XE7Lib A80 I had to make the XE7Lib entry A80 to accommodate items such as TComponentBased.Vcl.Controls.TControl in the above example and half that to accommodate AdvGrid in the D7Lib field. TMS Grids went into the Pg field and the two In fields were boolean fields. TAdvStringGrid was the Comp Name. I did this to clearly map where the Comps were that weren't common between the two versions, with special interest in the InD7 but NOT InXE7. I was surprised to find that a few of my OWN written components failed to make the trip to XE7. Which I was able to rectify quickly. This has helped me attack an upgrade mission. I'm still pretty clumsy with ReFind. But I'm missing less stuff. I'm still thinking about getting a list of properties between ReFind targets. I have a master dictionary of replacements, but it's still more trial and errors than science. Sigh. But with the PAL list and my little app, at least I know where the holes are. Will be watching this space to see how you are doing.
  14. Gary Mugford

    With's the deal with "With"?

    Regardless of whether using WITH is a good idea, there IS a solution ... The Convert WITH expert in MMX. It's not perfect and I always take the step of DUPLICATING the block I'm playing with and commenting out one copy, but the expert does a VERY GOOD JOB MOST OF THE TIME, in converting WITH's to object-referenced individual lines. I know, because I was one of (if maybe not the first) the early requestors for this expert. I'm a self-admitted WITH user. I find it easier on my eyes because I indent more than most. Albeit only two spaces per indent. With Uwe doing such a great job keeping MMX alive ... and for a most reasonable price 😉, whether you use it as a crutch early in development or go back through on refactoring passes, the decision to use WITH is only an installation of MMX from being made to go away.
  15. Gary Mugford

    IDE changes monitor when debug run

    A version of this problem goes back to at least Delphi 7. I have most of the IDE and forms on the left monitor, the source code window and some of the other windows on the right monitor. I'll click on the menu and then options (yes, there are hot keys and/or icons in both the IDE and the Editor to do the same thing, but I'm old and set in my ways) and the Project Options will open up in the middle of the right monitor, even past the edge of the Delphi setup itself (I always have visible windows monitoring this that or another in the remaining space on the right). I click on the UltraMon button to move the dialogue back to the left monitor, but the next time I go get it via the menu, it's back to the right. Never learns my preference. Now, is it different if I use a button or a hotkey? Don't know, never occurred to me to find out ! Still, it's indicative of this being a long-standing problem with Delphi. For whatever that's worth. GM
  16. Gary Mugford

    ReFind Examples sought

    Hello, I'm looking for examples of ReFind processing files for updating Delphi source code and DFMs. The ReFind.exe that I have access to is File Version 21.0.17707.5020 (which I assume means v21, July 7/17 run 5020, but I could very well be wrong). I know how to write lines for the file to unuse units and to swap one component to another. But what I'm looking for is how to change the property of the outgoing object to a different property in the incoming one. For example, Change the TABCRotLabel.caption to a THTMLStaticText.HTMLText.strings which is a strings property encapsulated in round brackets That's the most complicated of the changes. Sometimes, the property is a .Color to something .Color, but about three layers deeper. Just using the ReFind swap instructions doesn't do as much as I would like. I'm HOPING ReFind is capable of doing this. I had a subscription to DelphiParser but let the sub lapse without use because the timing was impossible at the time the license was valid. I was offered a free extension and accepted and didn't use it. I've got excuses, but not the chutzpah to go back yet again, now that I'm more ready and in condition to accept help. So, I'm trying to dig into ReFind. Looking for example lines so that I can play with them with my own code. The components that I'm swapping are not common today. They were around the turn of the century, but that's a long time ago. Links and actual examples and hints and warnings are greatly appreciated. Thanks, GM
  17. Gary Mugford

    keyboard shortcut for activating the code editor

    I didn't realize fully that you were looking for FREE key combos, not a solution to having a key combo FOR the purpose of going to the editor. My apologies. I STILL think it would be interesting if you found a way to USE KEYLOCK, if it's been disabled for it's express purpose. It's the most unused key on my keyboard. I'll leave the rest of my answer in place because it does deal with the actual mouse/trackball experience I have. The weird thing, is that it was a need to learn to program in AutoHotKey exercise that got me looking into my OWN tab-switcher in XE7. In reality, I have my left hand on the keyboard and my right (the dominant one) on my very, very, very old Microsoft Trackball Explorer. It's one of life's GREAT tragedies that I was writing the operations software with a company that got bought up by a big concern from the States. All new software (meaning I was a goner) and, as it turns out, new hardware, orphaning TWELVE Trackball Explorers. I could have had them all. They ended up being THROWN OUT IN THE GARBAGE. Double and Triple Sigh. That was last century. My TE gives every bit of evidence it will die and there's not a reasonably good trackball on the market with mostly thumb action on buttons and the scroll wheel and a BIG ball under the fingers. I've bought just about every thing Logitech has produced and their first, the long skinny one, would be the winner if it had a scroll wheel. THAT invention was still years off. I've got pens and trackballs and a couple of lazer mice. Every time the TE gunks up and I clean up the positioning pins and put the wiped off ball back, I get that little bit of relief I didn't kill it on the cleaning table. But it WILL die eventually. I plan to be buried with it.
  18. Stefan et al, I am an old fogey who generally keeps programming in a style you'd recognize as Mostly 80's Enlightened. Problem is, it's thirty/fourty years later and Delphi has moved on. I've spent some effort this spring trying to get into Interfaces. Read Nick Hodges' first book, browsed through the second and stare blank-faced at the third on my reading list. I'm getting maybe half and that's actually a tribute to Nick. I'm the old dog trying to learn new tricks. This thread has hammered away at global vars and singletons. And I can't see my way around them. At startup, my apps normally load a record called Globals. In there, the user info gets stored, as it's referred by a lot of code. Plus program settings and other miscellany. I DID have them as UserName, UserShortCode, UserSecurityLevel, but graduated (apparently, barely) to Globals.UserName, Globals.UserShortCode, etc. Now, I am looking at an interface approach. I have a date pair that comes from ranging requests in many reports and queries. The interface I'm fooling around with, in a completely separate unit, would lead to DateRange.Date1, DateRange.Date2, DateRange.DateSpan, DateRange.Date1Str, DateRange.Date1EasyRead, etc. There's more. A bunch of properties that I have logged using a Date in any fashion. My idea is to do all these transformations and have them done and ready when I need to create an interface, populate it with either two copies of the same date or the two actual dates, and then use a property immediately. I plan to dispose of the interface if no longer needed, but occasionally to keep it around while the form (say, the Report Manager) is active. This plan looks dodgy from what I've read here. I'm TRYING to look at this from other angles, but I still come back to global vars to hold items of interest, whether straight old-fashioned variables, record contents or interfaces. Can you point me in the right direction? Thank you for your patience. GM And I apologize for semi-hijacking this thread
  19. Wish I was, although it sits in the component library. I use the TfcDBTreeView from Woll2Woll's First Class components in my mapping module. It runs off a self-referential database that has Key, UltimateParent and Parent fields to create the TreeView. The Object itself is dead simple: object tvMap: TfcDBTreeView Left = 4 Top = 27 Width = 367 Height = 518 BorderStyle = bsSingle TabOrder = 1 DataSources = 'SourceRoot;SourceNodes' DisplayFields.Strings = ( '"Key" [Desc] "Desc" [Op] "Operator"' 'Uses "Errors" "Key" [Grade] "Grade"') LevelIndent = 19 end Nothing there that VT can't duplicate and you've already done it for your datasets. Now, as for the code ... Again, dead simple and maybe not sophisticated for your stuff, but it works as a self=referential tree exactly as I NEED it to be. procedure TFrmMap2.tvMapUserExpand(TreeView: TfcDBCustomTreeView; Node: TfcDBTreeNode); var qChild: TQuery; sourceChild: TDatasource; begin if (node.level + 1) < tvMap.displayfields.count then exit; { Create new detail paramaterized query } sourceChild := TDatasource.create(self); sourceChild.name := 'ChildDataSource' + inttostr(node.level + 1); qChild := TQuery.create(self); sourceChild.dataset := qChild; with qChild do begin qChild.sql.assign(qNodes.sql); qChild.databasename := qNodes.databasename; if lastds = nil then qChild.datasource := SourceNodes else qChild.datasource := lastDS; qChild.active := true; end; with tvMap do begin DataSources := DataSources + ';' + sourceChild.name; displayfields.add(displayfields[displayfields.count - 1]); lastDS := sourceChild; end end; procedure TFrmMap2.tvMapCalcNodeAttributes( TreeView: TfcDBCustomTreeView; Node: TfcDBTreeNode); begin { Determine if expand button should be displayed by using a lookup table } node.haschildren := TblLU.Locate('Parent', node.dataset.fieldbyname('Key').asstring, []); // node.haschildren := // TblLU.Locate('Parent Index', // node.dataset.fieldbyname('index').asstring, []); end; procedure TFrmMap2.tvMapChange(TreeView: TfcDBCustomTreeView; Node: TfcDBTreeNode); begin { Synchronize table bound to edit controls } if node.DataSet = qRoot then begin TblView.active := false; end else begin TblView.active := true; TblView.locate('Parent;Key', varArrayOf([node.dataset.fieldbyname('Parent').asstring, node.dataset.fieldbyname('Key').asstring]), []); end; end; procedure TFrmMap2.TbLViewAfterPost(DataSet: TDataSet); begin qNodes.active := false; qNodes.active := true; Application.ProcessMessages; end; Now, I HOPE I didn't induce any errors into the code trying to anonymize it. But you can see it's a minimum of code and I get the ability using the hierarchy fields to keep me functional. In my case, a Key has a Parent and that Parent, somewhere UP the line has an UltimateParent. This allows me the ability to move things around. Adapting it to YOUR case, I'd see the UltimateParent being FiledTo or somesuch thing. The Parent being some combination of Examined with Contents. And Key, of course, would be your document by title. The rest of the fields would be displayed by a Record View to the right or bottom of your tree or wherever. I would then write your text search routines to bring up unanalyzed documents by type and then keyword analysis. Throw in whatever else your AI deems as important in descending order of importance. Then scroll to your heart's delight, although technically, if all the AI has been well-written, the guess is that you scroll and read, one at a time. OVER-SIMPLIFYING by a lot, I know. But Peter is right when it comes to the viability of scrolling through the kind of list. I don't know HOW you decide to stop and read, but it HAS to be quantifiable. So says the guy who's never seen the code or the data. For which I apologize for my hubris. Wish you well in getting REAL help here. GM
  20. Ahhhh, I understand better. I thought it was more along the lines of something I do in a different milieu, which is to track essay submissions for a prof that I'm an occasional Bridge partner with. So, the random names of the essays he's looking for fall into, I remember it was two semesters ago and it was Joe or maybe John, writing on murders or maybe attempted murders of journalists in one of the ex Soviet Union republics. THAT I can narrow down. Yours, not so much. I assume there's a boolean field that marks a document as examined. Is there a facility to convert the PDF to a text document so you can index the words, or is it a truly examine them one at a time situation? And after examination, do you rename the file, discard it or leave it as is with a descriptor field? Feels like this might be a legal evidence app. As bad as OCR is with bad scans, there should STILL be a way to prioritize the ORDER of examination to maximize the time taken looking at them. Even if the KEY WORDS (I CONFESS) fails to be OCR'd correctly, the surrounding text might hit your eventual ordering algorithm. I've seen some impressive results with OCR these days with a little training. Eighty percent on a bad page I though virtually unreadable. And even the fabled 99 percent still has an error every line and a half. Somewhere in between, let's call it 90 percent, means an organizational improvement of, well, 90 percent. Worth the time to seek out the PDF conversion libraries and write yourself something for the computers to do overnight and on long weekends. Now, if there's nothing automatic out there (I've seen lots of apps, many of which CAN operate on command lines) then the labour/result graph might be wrong. But looking at 30K badly scanned PDFs makes my eyes bleed just thinking about it. Lots of luck, GM
  21. Mark, I ran into your problem in a different way a while back. I had a huge jumble of data buried in a memo field and needed a way to surface it, while having my user mumble those hated words, "I'll know it when I see it." What I did was say, "What will it look like?" And he described a title that might have this word or that word, a date from roughly this six month period and some other attributes. In other words, he DID have a list of parameters, however vague. So, I wrote what I hope was a smart filter that gave him fields for his 'descriptions', allowed there to be ANDs and ORs in EACH of those fields and a button to FILTER. From millions of records, he often ended up with the exact one. But if not, it was within a screenfull's worth of data. Using a 'filter' set that you process AI-like with a button push running a SQL query, could be a solution. Setting up the VT off that returned dataset might save you a lot of fidgety work. The task is to turn vague descriptors into actual query WHERE parameters. Yes, that will mean User Education but the time spent doing that, saving time scrolling, should be a win-win. Think more GOOGLE and less YOUTUBE Cat Videos. Not that I would EVER be caught watching kittens. I think you're letting the user off the hook. They/He know more about the thing they are searching for than they are telling you. I've done away with 'scrolling grids' in my latest version of my big project. Since I tentpole around one specific field in just about all databases in the project, it's easier for me to do that. But it was a hard decision to abandon the grid that showed just the few fields that were keys somewhere in the design. I watched users ALWAYS go to Ctrl-F to find what they were looking for. Then, when they DID decide to traverse the grid, it was rarely more than a single Next/Prev click. So, I just abandoned the grid entirely, put the Find buttons (there's an Again button) between two one-record movement buttons and that was it. In the menu, there's a popup for a grid CENTRED around the current record. And I've seen it used. Twice. I actually had a counter and kept track of how often the menu item ran. BREAKING myself of how I WORKED, which was scroll and scan frequently, into USER MODE where search and work was the mode, only took 25 years. All of this blather might not directly address your issue. It all centres around that user's inability/ability to at least reduce the total returned dataset by some. I know when I go spelunking to find data, it's always the LAST ONE I LOOK AT. Murphy's tenth law, I believe. I just can't imagine having it be the thirty THOUSANDTH thing I looked at!!!
  22. Gary Mugford

    Get UserID from LogIn form at startup.

    Sage advice. I've been through SOME puzzles coping with DPR manipulation by the IDE. It's why I keep a commented complete copy of the code that resembles my sample, PLUS having the DPR in my versioning software from AJC. Because of long term comfort, I've continued to do it, but like many things (including my change in database backbone), maybe it's time to do things the way the professionals do. The thought that my way of DPR manipulation might have crept into the issue I've had with BDE and Windows 10, prompted me to ask about the comment in TPersistent. Thanks, GM
  23. Gary Mugford

    Get UserID from LogIn form at startup.

    Remy, Ian et al, Oddly enough, within the last few days, Larry Hengen at TPersistent also raised this issue, but in the course of doing the blog, he said, " Any long time Delphi user knows that messing with the generated DPR code in Delphi can cause all sorts of grief later when Delphi tries to auto create forms and add units to the uses clause." I've long 'fooled' around with the DPR in my programming, which might only further prove my lack of bonafides. I've noticed a noisome habit of the IDE to play around with the lines I use to create my data modules, eliminating the indentations. But I correct them. Add other data modules. Correct them again. and so on and so on. I haven't found anything grievous to this point. What am I missing? Oh, and obviously, I have to fess up to still using Delphi 7. Here's the 'annoyance' in action. I've obfuscated some of the stuff for the obvious reasons ... begin Application.Initialize; // 3/14/2003 6:06:12 PM ED: Moved this from main form create gmSetPrivateDir; session.addPassword('STILLLEARNIN'); // NOT the password Application.Title := 'SYS:2011'; DlgLogin2 := TDlgLogin2.create(nil); with DlgLogin2 do begin TblPw.DatabaseName := 'SYS'; TblPW.TableName := 'NotAPasswordDatabase'; TblPW.Active := true; showmodal; if ModalResult = 1 then begin // create main form and data modules Application.CreateForm(TFrmMain, FrmMain); Application.CreateForm(TdMain, dMain); // always resets to col 1 Application.CreateForm(TdLU, dLU); // always resets to col 1 Application.CreateForm(TdmRep, dmRep); // always resets to col 1 Application.CreateForm(TFrmHistorySearch, FrmHistorySearch); // always resets to col 1 Globals.Version := '2011.8.8.'; // always resets to col 1 Globals.UserName := DlgLogin2.TblPW.FieldByName('User').asString; Globals.DEB := DlgLogin2.TblPW.FieldByName('MiniID').asString; Globals.RandomDateNum := CreateRandomNumDateInt64(0); if Globals.DEB = '' then Globals.DEB := 'UNK'; Globals.SecLevel := DlgLogin2.TblPw.FieldByName('SecLevel').asInteger; //----------Security Levels--------Enable/Disable Menus--------------------- FrmMain.mManager.Enabled := (Globals.SecLevel >= 80); FrmMain.mExecutive.Enabled := (Globals.SecLevel >= 90); FrmMain.mProgrammer.Enabled := (Globals.SecLevel >= 100); FrmMain.mODefaults.Enabled := (Globals.SecLevel >= 80); FrmMain.mOEditCustomer.Enabled := (Globals.SecLevel >= 75); FrmMain.mOSuperCusEd.Enabled := FrmMainOT6.mOEditCustomer.Enabled; FrmMain.mEDupePart.Enabled := (Globals.SecLevel >= 80); //---------------------------------------------------------- txt := gmPrinterName(False); FrmMain.StatusBar.Panels[3].text := txt; txt := uppercase(txt); if (pos('HP',txt) + pos('LEX',txt) + pos('XRX',txt) + pos('XEROX',txt) + pos('SAMS',txt) + pos('KINGS',txt) + pos('PDF',txt) + pos('BROTHER',txt) = 0) then ShowDlgOops('WARNING: You''re default printer is not on ' +'the standard printer list. This could be because ' +'you are signing on from a computer that you have ' +'no prior account with and the list of default ' +'printers has not been installed. Be aware of this ' +'when trying to print. You might have to switch ' +'printers or contact me to get printers ' +'installed'); FrmMain.StatusBar.Panels[4].text := Globals.DEB + ' / ' + intToStr(Globals.SecLevel); DlgLogin2.free; dMain.mTblPW.close; Application.Run; end else DlgLogin2.free; end; end. As you can see, the lines right after main forms createForm line always revert to flush left. I space them over, save the DPR and the next time I go to edit it, they are right back where they started from. Finally, I stopped worrying about it. I have a Globals record that is brought in through a unit specifically designed for it, that I can share around all the apps. DEB stands for DataEnteredBy and is a short indicator of the full name. SecLevel is Security Level and it's on a 30-100 gradiant with me being the only 100 and the Boss being a 99. The minions fall somewhere short of that depending on oversight capability. I make menus appear to people who have the title. I check for printers because in doing so, I also check to see whether they've signed in from a fully-setup account in the process. Guess that's about it. I know it's not artful and WHO knows whether it breaks down in newer versions of Delphi. But what is the grief? Thanks, GM
  24. Gary Mugford

    Blast from the past: BDE and Win10 W/S

    Before I start, I have to confess to be trying to rewrite the systems software using NexusDB. Progressing, but but not fast enough. In the meantime, our decades-old app is encountering pervasive corruption issues with BDE using Paradox file formats, Windows Server 2013 and NOW mostly workstations running Windows 10 and kept up to date. The problem started with the Fall 2017 update to Windows. Ever since, we have had a regular series of Blob is Modified and Index out of Date errors. We cope by having all seats (approx. 50) get out of the app and associated programs. We run reBuilder which is a modified version of PdxRbd. Then it's back in and we wait for minutes, sometimes an hour when the cycle repeats itself. Sometimes we get people jumping back in early during the rebuild and THAT EATS THE DATABASE with a not that there has been a sharing violation. Luckily, we do zip up a copy of the raw data before hand and can recover in that circumstance. But it's a LITTLE stressful to see major databases disappear from one minute to the next. And when it happens when I'm not there, the place ACTUALLY STOPS WORKING with the computer. Everything goes manual and that is NOT a good thing in today's world. I have theorized that this issue is related to continuing problems with BDE locks and Windows locks going out of sync, if they were ever IN sync. That said, I'm no Windows tech expert. Might be something else. Probably is something else. What I am looking forward is a settings that can make BDE work in the Windows 10 environment the way it STILL WORKS for Windows 7. I don't have the ability to retrograde the OSs for the Work Station, although I spent a night writing up a proposal to do exactly that. The answer was no. Find another way. And I haven't. The non-answer has been to make the workers' endure the stop and start operation that occasionally results in unrecoverable data loss (mostly lines out of history memo fields). And it's getting a LOT worse and I'm still too far away with the NexusDB operation to look my fellow workers in the face. So, I'm reaching out to you DATABASE EXPERTS (give yourself a pat on the back just for coming here to help out people like me) and see if any of you can remember back to when you ran BDE. Or might STILL be running BDE in a small controlled environment. And can suggest a setting, a tool, a whatever. I HAVE started running a virtual box test, but the Workstations all have minimal RAM and having half of it taken up by a vb that is running a short-memory Win7 environment to run the app, turns out to be glacially slow. Although it DOES work. So far, we have two computers set up that way and the hardware guy says he can average three more a week. Which means I would have possible solutions up and running some time in the late spring. At which point, I would hope my direct solution might be ready. So, as much hope as I had originally in the vbox concept, it's NOT the solution for the immediate crisis. Regardless of whether you have an answer, I thank you for taking the time to read this. I hope you and yours have the Merriest of holiday seasons and a sane and safe Happy New Year! GM
  25. Gary Mugford

    Blast from the past: BDE and Win10 W/S

    Jobo, Turns out I HAVE been to Karsruhe, but I don't remember it. My mother enjoyed the day trip there and so did Dad, apparently. My only vague memory is of fun in Madurodam in The Netherlands. Your best wishes SEEM to be having some success, so keep 'em crossed. Thanks for that. NO drama on Monday. None on Friday of last week too. Another respite like this, and maybe we can declare the problem curbed, maybe even eliminated. Steps taken in no scientific method, so I don't know what had the best effect ... Confirmed all Paradox databases were Level 7. SIX databases provided by customers proved to be Level 5. I also made the Block size 32768 on all tables, about 20 were various sizes less than 32768 but none of them were approaching their record limits Had the registry setting suggested by Uwe Raabe added to the server. Went through EVERY table object in ALL applications and confirmed that dbiSaveChanges(tbl.Handle); was in the AfterPost event. Confirmed a clean bill of health. Switched the alias used to use UNC notation rather than direct mapping. Previously, had changed the shortcut of the apps on the Win10 workstations to run the program (whichever one it was) in Windows 7 emulation mode. I'm not sure if the microburst disconnection article prompted any changes by The Hardware Guy. But obviously mission critical if those disconnections are why we are running into Index Out of Date. Do I believe I have found the secret mix to make BDE behave under Windows 10? No. Slow it down? Maybe. And as long as good-hearted helpers are keeping their fingers crossed, maybe an intolerable situation with a deadline of yesterday, or the day before, or last year or last decade, becomes something to concentrate on getting a good replacement out, rather than A QUICK replacement. Thanks to all. GM
×