ParentWindow in a DLL - delphi

I'm trying to assign a ParentWindow, to a control created in a dll. The control is an editor, I need to process a text file, but this control requires a ParentWindow.
How can I solve this problem, if I create this control in a dll?
I'm using Delphi 5.

also create the TForm (maybe not Visible) inside the dll then the control and add it to the form

This is a common question, and the correct answer is "Don't do that".
The first question I have is "why do you feel the need to create a control in a DLL?" Why not just create it in code or include the control itself in your EXE?
Second, if you want to add a control to a separate binary, but it in a Package. Packages are designed specifically to make exporting controls simple and easy.

You need to get the parent window from somewhere! Typically the host application that loads and calls the DLL would supply a window handle. It looks like your DLL provides a custom control for an application, so of course the application needs to supply a parent window handle.
Also, you typically need a window handle to the entire application as well, which you set as Application.Handle before you do anything else in your DLL.

ok, thaks for your answers, i already solved (a few minutes before first answer).
first, i need explain why i don't embed, and that is because costumer ask me that way.
the solution is send my form handle to my dll as an argument, after testing that way, i got no errors...
only modificate the prototype of my procedure, to recieve a HWND as an argument, to ParentWindow prop of my control (created in memory).
that's all.

Related

Using IOfficeAntiVirus interface in Delphi

Presently I am developing a small security application in Delphi. It is intended to be installed in Windows XP and higher OS-s and almost finished, but I'd like to implement the feature to scan MS Office files while opening. To that end, I'm planning to use IOfficeAntiVirus interface. I am trying to realize using the scan method of the interface based on the article by Serge Perevoznyk (http://www.delphi-central.com/MS_Office_AV_API.aspx).
The original example supposed to display a message box when a file is opened, however it does not, although I tried it on different versions of Windows and Office. I compared this solution with the information on MSDN. It seemed to be correct. I suppose there should be some additional settings in the Windows Registry which I missed to make. Can anyone give me some hint where shall I look for the solution?
You do not use IOfficeAntiVirus, you implement it.
You need to create a new ActiveX Library that contains a new ActiveX Control whose implementation class implements the Scan() method. In the Control's registration code, you have to use ICatRegister to register your Control as using the CATID_MSOfficeAntiVirus category. That way, Office/IE can find your ActiveX Control so it can instantiate it and call its Scan() implementation. The second half of Serge's article shows you how to do that (Serge's example shows Scan() taking a PChar as input, but it actually takes a TMsoavinfo^ instead. Don't pass TMsoavinfo using a PChar).
You then have to register the resulting DLL using Windows' command-line regsvr32.exe app.
If Office/IE is not calling your Scan() implementation, then you are likely not registering your ActiveX control correctly, such as if you are not taking 32bit/64bit and/or UAC issues into account.
Just for information's sake if anyone is interested. Remy's answer is correct, however there is a small bug in the initialization section of the above mentioned example project.
Instead of
TComObjectFactory.Create(ComServer, TMsoTest, Class_MsoTest,
'MsoTest', '', ciMultiInstance, tmApartment);
The correct command is:
TMSOAVFactory.Create(ComServer, TMsoTest, Class_MsoTest,
'MsoTest', '', ciMultiInstance, tmApartment);

Library to create forms/GUIs/dialogs from scripts?

At the moment, whenever I need a custom dialog, however simple, I use Delphi's form designer to create a new dialog form. The form is then wrapped in an easy to use ShowMessage() type function.
In some situations it would be easier if forms could be created at run-time from a script. The script would detail all form components and their properties, much like Delphi's .DFM files.
Creating GUIs from scripts could be useful in other situations as well. For example, a GUI of a mini application could be embedded into the window of an existing application. Or the GUI script could be modified at run-time to create GUI variations.
I could create something to do this myself, but I assume other people have already tackled this problem. However I can't find anything using google. Is there anything currently available offering this kind of functionality? (Free or otherwise) Or does it already exist in Delphi?
Check out some of the scripting solutions for Delphi. For example, the TMS Scripting Studio, dwScript, RemObject's, FastScript, etc. I believe some of them are able to use DFM's for this purpose.
http://www.torry.net/pages.php?id=280 Delphin v.1.21, it can process DFM files, maybe you just want the DFM to code converter.
You might try XI Library (commercial): http://xilib.com/
I have never used it, it's just something sitting in my bookmarks, but it looks like it fits the bill. Not a scripting engine, more of a way to define dialog boxes via XML. There's sample XML code right on the front page, just click "Show the example".

Is there a Delphi option to 'lock' the design (layout) of a form against accidental changes?

After years of Delphi development I now have hundreds of forms shared throughout our Applications. Compilation ranges from Delphi 7 through to XE, thus one form might be opened in any IDE. The well-known Explicitxxx property addition after Delphi 7 has solutions to avoid a form accidentally acquiring properties that earlier compilers can't process (e.g Andreas's DDevExtensions) but I'd like a more positive 'switch' that prevented Delphi from making or saving any form modifications at all. Period.
Of course you could use the read-only flag, and a version control system provides additional means particulay of seeing that such a modification has occured. What I'd really like though is a {$LockDFM} switch that I could put in the form's unit, or a context menu option when viewing the form layout.
Can anyone think of a neat way of achieving this?
Thanks
The only thing I can think of (other than the read-only/VCS options you mentioned) is the Edit menu's Lock Controls option. This sets a flag that prevents controls from being moved around. I'm not sure how much good it would actually do, as I've never tried it; I just know it's there.
Helo
I am pretty sure that Delphi has no such a thing. I have been searching for a solution to this problem as well.
But, theres one thing you can do: You can write your own Delphi addon using OTA (Open Tools API). I know that there are a few classes which are able to notify you when something are about to be saved. You can intercept this event and decide if you wanna save it (in your case, if it is a DFM).
BTW, if you have plans to do such component, tell me. :)
EDIT:
I have found a piece of code that may help you. Extracted from http://www.gexperts.org/otafaq.html
TMyFormNotifier = class(TNotifierObject, IOTANotifier, IOTAFormNotifier)
protected
procedure FormActivated;
procedure FormSaving;
procedure ComponentRenamed(ComponentHandle: TOTAHandle; const OldName, NewName: string);
end;
In design time there is Edit->Lock Control.
LE: this is only for resizing/repositioning the controls on the forms. Concerning the ObjectInspector I don't know if there is anything that can 'lock' the values set there(so the developer can not change them).
Basically, no. Aside from the f'ing (pardon my french) explicit size and position properties which IMO never should have been in the .dfm, there are some third party components will change stuff just by you viewing the form. F.x. TMS components will update a version number even if you didn't change a thing since the previous version of their components.

Visual Form Inheritance problem. "cannot inherit from (parent form). Contains a component that does not support inheritance"

I have a base form with descendents. The base form has a TElRelDataSource on it (from ElPack v4.00). When I open the descendent form I get an error "cannot inherit from (parent form). Contains a component that does not support inheritance". This is with the ancestor forms open (there are two), to avoid the "ancestor for (parent form) not found" error.
Delphi 7 doesn't (AFAIK) support finalising classes, but this seems to be a standard error message. It's in the index for "Tomes of Delphi: Troubleshooting" but I don't have a copy of that and I'm reluctant to spend $US60 to read an entry like "this is why you should avoid VFI" (being pessimistic about the contents of the book). Other than that, no references in Google or Bing.
This is in code that I've recently inherited from someone who left a while ago and I'm the first person to change it since they left. Which means I can't ask how he created the offending form.
So, how do I get around this error message?
You got yourself into an interesting problem. First of all, you say the parent form already includes the offending DataSource, so you've got to ask yourself a question: How did the original developer manage to put the dataset on the parent form and then create child forms, if creating child forms is rejected by the datasource?
The original code didn't have the TElRelDataSource
This implies you're trying to add it your self. Don't add it, find an other solution that doesn't rely on the TElRelDataSource.
The original code did have it!
The original was probably compiled against a different version of TElRelDataSource, one that did allow inheritance. "Inherability" is controlled by the "csInheritable" component style. That is, if the component doesn't include "csInheritable" in ComponentStyle, the Delphi IDE will not allow visual inheritance. You have a number of options:
Use a different version of TElRelDataSource, maybe the original was compiled against a NEWER version of TElRelDataSource. If you are using the latest TElRelDataSource, the author probably decided it's code can't handle visual inheritance so he/she removed the csInheritable flag from ComponentStyle!
Try making your own derived component and set that style yourself. This is easily done, but if TElRelDataSource's author removed the csInheritable flag for a reason, you'll probably get into trouble.
Normally HeartWare's idea would work just fine; Unfortunately it's not that easy with a DATA SOURCE component: I assume you have DB-Aware controls linked to that data source. If you create the DataSource from code, you'll need to re-create the connections to data-aware controls as well, and that's going to take a lot of "if-s" (or clever use of RTTI).
You may try moving the DataSource to a TDataModule. This is probably more trouble then it's worth it.
One option would be to remove the offending component from the form and allocate it dynamically in the FormCreate event. Depending on how many properties the (presumed) non-visual Data Source component has, this could be fairly simple.

how to load delphi tframe from dll to delphi application

i have created a dll with tframe .
how can i load it inside my application, i dont like to use bpls , i only want to destribute exe and dlls with my app
Since a BPL is a DLL, go the BPL way: much easier.
It can be done but it's a hell of a job to get it working without errors or memory problems. To make matters worse, you will be using two VCL's in your application, one in your executable and another in the DLL. Your frame would try to refer to the DLL VCL, which would provide very different information than the EXE VCL. Especially when checking the global Screen and Application variables.
Still, a frame is nothing more than a special window control, just like forms. You could export a function from your DLL which would return a value of type TFrame. Your application would be able to call this function and thus create the frame, use it in any way it uses all other frames. It won't have any specific information about additional functionality within your frame, though.The next thing you'd have to work on is to synchronize the data between the EXE and the DLL that is VCL related. That's not very pretty. Plus, you will probably have some issues when using the tab key to tab through the controls on your screen, since the tab key won't be able to tab outside the frame. And you will notice a few more oddities like this.
I have worked on a simple application that used frames this way. Me, and two others spent two months getting some working solution, which did work reasonable well without memory leaks and other troubles. Before we started that project, it just seemed like a good idea. Afterwards, we decided that it didn't turn out to be the solution we'd wanted so we merged the code of the DLL's with the code of the executable to just create one executable. It was better that way.
We did use another alternative, though. We started using a webbrowser component in the mainform. The DLL would contain a HTML page, nicely formatted, and a bunch of methods that would be called when certain specific functions were used. We had this working in a simple test application with good results but then the company went chapter 11... My employer went dead broke since a deal with some customer misfired badly, leaving the company with some huge debts. And thus an interesting project ended...

Resources