Heading : How can I read a StringGrid content in another application's window?
I could get the StringGrid's handle
A Delphi string grid is a pure VCL control. You cannot use windows messages to read its content. You cannot use any of the automation APIs because Embarcadero do not and have never made their controls accessible. For which, incidentally, shame on them.
The only viable way to do this is through gross hacking. If you know the memory layout of the control you can read its memory the same way as a debugger does. Using calls to ReadProcessMemory. However, this will be exceptionally messy and hard to achieve.
A simple approach would be to inject a DLL into the target process. So long as your DLL is built with the same version of Delphi as the target process, there's a reasonable chance that you'll be able to read out the contents of the grid. You can then use IPC to send the information back to the other program.
Note that none of these solutions are remotely appealing. If you can find a cleaner way to do this, possibly avoiding this target process altogether, then you should give it strong consideration.
Related
I don't understand LiveBinding's purpose. I would like to know which are the cases in which LiveBinding is most valuable. Embarcadero's manual describes it: "LiveBindings is a data-binding feature supported by both the VCL and FireMonkey frameworks in RAD Studio. LiveBindings is an expression-based framework, which means it uses binding expressions to bind objects to other objects or to dataset fields".
Thanks but I still don't know more than before.
I have seen some video in which a guy spends 12 minutes and hundredths of clicks to connect the caption of a TLabel to a TListBox control. When the user clicks an item in ListBox the name of the item is shown in Label. I could have done that with a single line of code (few keystrokes and no mouse clicks).
I am not criticizing LiveBinding. I am saying that I don't understand where it is helpful. I am missing something. Since it is not doing something that cannot be done from code, it means it's doing something that can be done from code, but visually and much much faster. I admit I haven't invested a lot of time in this topic but everywhere I look I see a terribly convoluted way (come on, you really need 5 extra controls to make LiveBinding works?) to do a simple task.
Also, it seems that LiveBinding was mostly designed for DB. All examples will include some kind of DB connectivity. But I am expressly interested only about the cases where I can use LiveBindings and there is no data set/DB involved. I am not using DB that much.
I doubt v. much that anyone would use live bindings if they could use traditional db-aware VCL components. However, that's not an option for non-VCL projects (Android, Apple, etc) and live bindings is the only Emba-supplied option for delivering data to those from TDataSet descendants.
An advantage of live bindings is that in addition to the Android and Apple targets, you can use them in Windows apps, so conceivably you could write the same (FMX-based) application for all three.
Libe-binding can also be used in VCL applications, but tbh, I can't imagine why anyone would use live bindings if they were only targeting a Windows DB application, as they are much slower than the traditional db-aware controls, especially multi-row ones such as grids.
I have not tried myself, but because the implementation of live bindings is interface-based, its potential use extends far beyond DB applications, but you would have to implement the interfaces yourself. It seems to be based around a fairly abstract expression-evaluation engine.
Setting up a l.b. project in the IDE does seem to require quite a bit more clicking around than you'd be used to from a traditional VCL app, but that's mostly because there is an additional step involved where you tell the IDE how to bind the gui objects to the data source(s). However, it is quite straightforward to "wire up" live bindings entirely in code if you want to.
Although it is comparatively hard to write in C++ than in Pascal I'm really attracted by multi-platform support of Qt. I can connect to an MSSQL server running on Win2003 server from Linux or I can connect to a PostGreSQL server running on Linux. That made a plus when comparing with Delphi.
I'm trying to write sample programs to get used to the Qt and C++. So far I'm comfortable with the layouts and signals-and-slots mechanism (still double clicking the buttons to write event code though :) ). I wish I was using the SQL data in my programs as easily as in Delphi.
Is there any way that I can put some connection object, a DataSource, a DBGrid and a DBNavigator on to a form and go on without writing code? (For some forms it is really a time saver, a project with 300+ forms can be made faster)
I would like to hear from people using Qt with data from SQL servers.
You would have to write your own designer plugins to achieve that and make your widgets invisible, as there is no direct support for non gui components in Qt Designer.
However, writing explicit code in Qt (which is really a lot less work than in most other programming environments) helps the program to stay readable. Delphi projects with a lot of forms and components tend to become readable to the author alone, because dependencies jump across files a lot. If you store your forms in binary format, you are lost anyway, because you then cannot search your project textually to find dependencies.
Good design, which causes your code to become small and easily readable is necessary in any programming environment and makes aspects like invisible components in forms less important (though you will miss them for a while to come like I do).
So, unfortunately, you are on your own for the moment.
I know there's an API for creating extensions to Delphi. I use the GExperts package and various JVCL experts frequently. But I've never seen any extensions to the debugger. It would be very nice, for example, to be able to register viewers for various objects instead of having to examine them in the Inspector. (A form with an image control that displays a TImage, for example, or a grid that displays the contents of a dataset.)
Are there any APIs that allow you to extend Delphi's debugger in this way?
EDIT: This wasn't available back when I wrote the question, but Delphi 2010 provides a way to do it.
In ToolsAPI.pas source there is some API interfaces for debugging. You can be informed when a debugging event occurred, info about breakpoints, which process is being debugged etc. with this API. But it seems there is no support for variables or values of them. So there is no easy way to implement your requisition without ugly hacks.
Basic debugger visualizers can be implemented with the Evaluation interfaces exposed by the OTA. (Examples for debugger visualizers can be found here and here.)
A deeper integration into the debugger is possible as well (for example, I wrote a little extension for C++Builder that enables the debugger to evaluate the actual objects behind an interface) - but as Khan pointed out, to achieve such a level of integration, you'll need to resort to quite a few dirty hacks.
I need to speed up my coding, too much work, so I need be able to generate code.
Any tools, any ideas?
Delphi includes Live Templates, a completely scriptable and configurable system for generating code constructs of any size or complexity.
Live Templates are, in my view, one of the more under-appreciated features in Delphi.
Find out how to use them at: http://delphi.wikia.com/wiki/Delphi_Live_Templates
and
http://delphi.wikia.com/wiki/Live_Templates_Technical_Info
Live templates are completely scriptable, meaning you can write Delphi code to do whatever you want with them.
An extendable example can be found here:
http://cc.codegear.com/Item/26420
Not a very good idea IMHO. If you need generator, then probably you have lots of code that looks very similar, so instead of generator, better thing would be to rethink and refactor code you have.
That should result in less code that is easier to maintain and less code in future for similar tasks.
If you are doing database application, then you could use some good visual SQL query builder to help you create queries. That is part that Delphi was not very good (I don't know if it improved in D2007 and D2009)
EDIT - Regarding SQL generation
There's lots of comments about query builder.
Well, I suppose I'm spoiled. As I remember, Delphi before version 6 (or maybe even 5?), had decent visual query builder. I had 0 (zero) bugs in SQL when I selected fields in query designer, opposed to writing SQL by myself.
SQL is just string in Delphi, there is no compiler checking, so this was the best way to ensure that SQL is correctly written.
If you mean something like a modeling tool, you could try out ModelMaker.
Rather than trying to code generate, you should probably just obtain code to do the bulk of what you want to do.
There are hundreds of free products at Sourceforge for Delphi.
And there are hundreds of thousands of code samples at Google Code Search that you can use.
Plus lots thousands of free or purchaseable components at repositories such as Torry's Delphi Pages or Embarcadero's Code Central for Delphi
Using components already made is the fastest way to speed up your coding, and to add capabilities that you would never have been able to.
For me best way is by creating custom components, and then create designer for this component.
I have find that i spent most of the time writing code that read/write values from controls. So i created control that can read, write, validate values, and automatically fill form or stored procedure or directly generate SQL and execute.
Custom designer allows you to setup all properties easy. Now i don't write code for such trivial task i just put control , open designer and set properties and rules that must be satisfied.
ModelMaker Code Explorer speed up my coding in times. It has a nice hotkeys for synchronising implementation and declaration, so if you changed one, you don't have to search for it pair. Also, very nice feature is, method editing dialog. And many more.
Have you tried GExpert? It is a set of tools built to increase the productivity of Delphi and C++Builder programmers by adding several features to the IDE. GExperts is developed as Open Source software.
Other alternative is using project template by saving a framework into the IDE Repository, create your own components and frames.
I wrote a code generator calle CodeTypo. I'm used it in many production environment. You can find it here: http://dade2000.altervista.org/index.php?page=CodeTypo
It's still in beta phase but is usable and reasonably stable.
I'll migrate all content of this old site in the new one (www.danieleteti.it) in english. And I'll add some other info about CodeTypo and code generators.
The thing that sped up my Delphi coding the most was getting CodeRush for Delphi (via a DevExpress VCL subscription for Delphi 5, 6, 7) and setting up a ton of templates.
I need a few of my related applications to communicate to each other (exchange data and initiate actions). Requirements are without packages and no sockets. So I guess that leaves named pipes, WM_CopyData (like Skype does it) and command parameters. What are your best practices?
You probably have a couple of options.
Beyond what you already have:
DDE
Memory Mapped Files (MMF)
MailSlots
I would probably go with either the Pipes or the MMF.
There are a couple of free MMF components that you can download,
Deborah Pate has a set of freeware classes you can use.
MapFiles.zip
Check for MailSlots on Torry's site.
The final solution might be dependent on the amount, size and frequency of the data transfers that decide which option you choose.
I would advise to use COM in this situation. (Attention: not COM+, not ActiveX, not OLE; COM, just COM.)
Since Delphi 7 (or an earlier version, I'm not sure), this is easily done by adding a Type Library to the project, and an Automation object.
Advantages are it's pretty widely supported, both within Delphi (the Type Library Editor has everything you need and updates your code, and COM internals and registering are catered for from the ComServ unit), and outside of Delphi (I use it in a number of project to interact with all sorts of applications: C++ projects, Word and Excel documents using VBA, oldskool ASP...).
An only disadvantage I encountered may be threading issues, in normal applications, a plain CoInitialize(nil); at application startup will do, in more complex applications, you need to think about 'threading apartments' or use free threading and do your own locking. (Which in some cases you've been doing already.)
Another alternative which is dirt simple to implement is to use the database to pass information.
Not overly elegant, and it does use a lot of overhead, but if your application is already data-aware (ie has a database as part of it), then using a table or two to pass information is pretty easy.
You could use simple files: One side writes to it, the other reads. If you need two way communication, just use two files, one for each direction.
Of course this is not really high performance.
Another vote from me for named pipes, for the data exchange. I like them slightly more than mmap files, since the win32 pipe APIs give you some nice choices out of the box: sync/async, byte stream vs message packets, simple ReadFile/WriteFile calls. All of which you could do yourself with mmaps... but pipes are already there...
And you can control access with security attributes -- which isn't an option with WM_CopyData. This might not be an issue immediately... but can be handy to have the option, even if you don't care who sends your app messages. For me, this was helpful when Vista came along, and suddenly user apps ran in a separate session to my service. Was good that tweaking the security attributes was the only thing needed to get things working again.
For "initiating actions", you might be able to get away with something as easy as some named Events, and not worry about sending messages at all? The interested parties simply wait for it to be signalled.
Personally, I'd avoid COM unless you have to specifically support COM-based clients.
Do not use COM, too much overhead (variants) and you must register you .dll or .exe (and it gives a lot of weird installation + update problems).
I should go for MMF, I use this for communication with Windows Services.
I use the following TGpMessageQueueReader and writer for this:
http://17slon.com/gp/gp/gpsync.htm
If you want to pass data, call functions etc then use COM, however if there are lots of calls be aware that COM is slow. Also you might have to register the application with "xxx.exe /Regserver", before it will work.
Is'nt this the sort of this that RemObjects is good at?
Bri