Hi

I'm looking at trying to resolve the issue of forms not working properly in DLLs, and thought canvassing opinions from those more intimately aquainted with the source might be beneficial. I know it's not slated to be recolved until post v1.0, but I can't wait that long!

What I'm currently looking at is using a mechanism whereby the host application maintains a list of additional objects (whether applications or forms) to it's own, and in the message-loop passes the messages to those first, before trying to process them itself.
This is similar-ish to how Delphi handles some of it (a call to SetHandle adds a ref to a process list which is checked in the message-loop), but of course the abstraction layers are different here, so something similar but different is required.

My current thinking is that when an app wants to use a form in a library, the process should be.

(i)   Library is loaded, either statically or dynamically
(ii)  DLL has an exported function 'SetHostApplication(HostApp:TApplication):TApplication;' before the host app can use a form, it must call something like DLLApp:=SetHostApplication(Application); and inside the dll the application object passed should be stored (in a global or whatever is appropriate), and its own Application object should be returned. The host and the dll now both know about each other.
(iii) After calling SetHostApplication, the received DLLApp is registered into an internal list in TApplication - let's call it fChildApps - using a procedure RegisterChildApp(DLLApp);...
(iv)  In the Host's message-loop it iterates fChildApps calling a procedure to attempt to process the current message [if it's keyboard or mouse related]. If it is handled, the host proceeds to the next message, if not it handles it itself. At the end of the loop, a call should be made to each of the fChildApps.ProcessMessages which calls the relevant Widgetset.AppProcessMessages.
(v)   When a dll is done, if dynamically unloaded, a call should be made to UnRegisterChildApp.

Hmmm - looks complicated!

What I'm currently wrestlting with is where the message handling should take place. Using the new PrcoessAsyncCallQueue is probably not the place to do it, since the mechanism is different. Ideally it would be nice to wrap stuff up on a high level, but pragmatically that's not going to happen, since each OS handles stuff differently, so each widgetset's AppProcessMessages is the place to implement the details of it. It may even be worth having an AppProcessSingleMessage..

OK, I'm starting to ramble, so back to the point.

Essentially I'm propsoing a system of callbacks, where a dll is registered with the host, and the host feeds messages back as appropriate. It will need to be implemented at both TApplication and TWidgetSet level, and do it gracefully. Also it will require a clear head on the part of end developers, but if the process can be stripped back to Host calls a single procedure to register/unregister a dll, and the dll writer accepts responsibility to export a function (or maybe two) then it could probably be streamlined quite well.

Caveats will need to be taken care of, like an application not being able to register itself in it's callback/child list. Messages should probably passed TApplication to TApplication, so that each message can be handled by the lower level widgetsets correctly (it could well be that a GTK application could load a dll using QT, etc). This will add function calling overheads so care will be needed not to kill performance...

It could be that TApplications are the wrong thing to be holding, and that just the TForms are what should be registered, but the danger here is of forms being freed without the DLL developer remembering to UnRegister the form, so doing it at the TApplication level should take care of that.

When implemented, a new item could then be added to the repository for 'Library with Forms', which has the correct exports already in place, reducing the developer error..

Right - who thinks what? :-)

Duncan Parsons

_______________________________________________
Lazarus mailing list
[email protected]
http://www.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to