View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0007182 | Lazarus | LCL | public | 2006-07-19 21:55 | 2019-10-28 09:39 |
Reporter | Phil | Assigned To | Ondrej Pokorny | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Platform | Intel and PowerPC | OS | Win XP and OS X | ||
Summary | 0007182: Problems using LCL in DLL | ||||
Description | I'm double-posting this because there appear to be several bugs and I'm not sure if they're in FPC or LCL. I've uploaded a .zip file containing test programs that can be compiled with either Delphi or Lazarus. GuiLib - VCL/LCL form in DLL ConsoleTest - runs DLL form from console app GuiTest - runs DLL form from GUI app When GuiLib is compiled with Delphi, it works with both ConsoleTest and GuiTest compiled with either Delphi or Lazarus. When GuiLib is compiled with Lazarus, works with ConsoleTest compiled with either Delphi or Lazarus on Windows. Does not work with GuiTest compiled with either Delphi or Lazarus on Windows (form is displayed but unresponsive). Does not work with either ConsoleTest or GuiTest on OS X using GTK widgetset (access violation). An apparent FPC bug is evident when GuiLib is compiled with -Ct (stack check). This causes DLL function to exit immediately. This is also the case with most of my non-GUI DLL's as well, so I don't see it as a GUI issue. Thanks. | ||||
Tags | dll, library | ||||
Fixed in Revision | |||||
LazTarget | - | ||||
Widgetset | GTK | ||||
Attached Files |
|
related to | 0007240 | closed | Yuriy Sydorov | FPC | unable to debug a DLL / DLL seems to be broken |
related to | 0007244 | closed | Peter Vreman | FPC | dynamic load of DLL fails |
related to | 0016611 | closed | Juha Manninen | Lazarus | Lazarus not open dynamic lib with LCL Form, but open VCL Form (Delphi), why? |
has duplicate | 0007181 | resolved | Bart Broersma | Lazarus | Problems using LCL in DLL |
has duplicate | 0001866 | resolved | Ondrej Pokorny | Lazarus | LCL not fully supported in library applications (.dlls) - Plug-in applications with GUI not working. |
has duplicate | 0026543 | resolved | Juha Manninen | Lazarus | AV when changing size of TBitmap in library which is loaded from Delphi |
has duplicate | 0028821 | resolved | Juha Manninen | Lazarus | Division by Zero or Out of Bounds errors if use TStatusBar component. |
has duplicate | 0020320 | resolved | Ondrej Pokorny | Lazarus | Problem to display a form that belongs to a library |
related to | 0015126 | resolved | Ondrej Pokorny | Lazarus | Reparenting forms within a library |
related to | 0026439 | closed | Juha Manninen | Lazarus | GlobalIdentToInt causes shared library to enter zombie state |
2006-07-19 21:55
|
|
|
I guess it has something to do with the ShowModal function defined in customform.inc. |
|
Ok, now that I'm more familiar with lazarus I found out at least one more problem which has to do with ShowModal. If for example within Delphi IDE a form is modal (for example an open dialog), any click to the IDE will bring the complete IDE to the top, focusing the open dialog (modal). In contrast to that any click on the lazarus IDE (outside the open dialog) will result in nothing! Only if I click on the open dialog itself it focus it and brings the whole IDE to the top. This may be related with this bug, but it isn't the root of all evil here. |
|
After some more investigations I 'fixed' the problem with showmodal. Anyway that still doesn't solve this bug, but I'm now more into this and with some more days it should be possible to find the solution, hopefully... |
|
By adding: {$IFDEF Win32} TWin32WidgetSet(WidgetSet).AppHandle:=AppHandle; {$ENDIF} to the GuiLib.pas and by writing an apropriate write method 'SetAppHandle' within the TWin32WidgetSet it is possible to open the modal form as part of the application, but that still doesn't resolve the bug :-/ Furthermore I think the PeekMessage() causes the problems, because I think it cancels out relevant messages. I'm not sure, but that is my suspect for now. PeekMessage() lets Paint messages go through, but nothing in relation to Key or Mouse input. It seems the window is disabled somehow. So far I found out the DisableApplicationWindows() function inside TWin32WSCustomForm.ShowModal() works fine, but if you comment it out it is also nonblocking (but also not modal anymore). |
|
Moved to Lazarus since I don't think this is a FPC issue. Problem here is when using the LCL from a DLL, you get 2 instances for TApplication. One in the Main app and one in the dll. The main app handles all events and the dll doesnt. So forms created in the dll don't respond to user input. Delphi has a way to link those tapplication instances by CreateApplicationHook. This way the application of the dll gets part of the main application loop. I lowered the severity, since this noway blocks a lazarus 1.0 release. |
|
Any news on this front yet? Right now it is even worse then it was before. Without the workaround for debugging DLLs it's impossible to debug and it only works without any checks in the compiler settings. Furthermore the external linking in Win32 doesn't work anymore. It always try to link a file uxthemes.dll here... |
|
Both DLL and mainprogram also have an full own copy of every unit it requires and their own state (classes + RTL, memory manager inclusive). Delphi has "sharemem" to resolve the memory manager problem on Windows. |
|
I'm ready to pay someone who would resolve this bug. Anyone? |
|
Modal form in a library works pretty well with Carbon widgetset on OS X and Laz 0.9.26 / FPC 2.2.2, so this is probably a Windows widgetset issue. If you need Windows, you could use Delphi. You could post a bounty too: http://wiki.lazarus.freepascal.org/Bounties |
|
Yes, I need this to use Lazarus to make VST plug-ins with GUI. Now I use Delphi but I hope that Lazarus have more future in code optimization / 64 bit OS support. Thanks for the link. |
|
//Here's my fix for modal form within a dll, for windows: library GuiLib; {$R *.res} uses SysUtils, {$IFDEF LCL} LclType, Interfaces, Windows, {$ELSE} Windows, {$ENDIF} Forms, LibUnit in 'LibUnit.pas' {Form1}; function RunForm(AppHandle : HWND) : LongBool; stdcall; {$IFNDEF LCL} var SaveAppHandle : HWND; {$ENDIF} begin Result := False; try {$IFDEF LCL} Application.Initialize; {$ENDIF} {$IFNDEF LCL} SaveAppHandle := Application.Handle; if AppHandle <> 0 then Application.Handle := AppHandle; {$ENDIF} Form1 := TForm1.Create(Application); try SetWindowLongPtr(Form1.Handle,GWLP_HWNDPARENT, AppHandle); SetWindowPos( Form1.Handle, AppHandle, 0,0,0,0, SWP_NOSIZE or SWP_NOMOVE or SWP_FRAMECHANGED); EnableWindow(AppHandle,false); Form1.ShowModal; Result := True; finally {$IFNDEF LCL} Application.Handle := SaveAppHandle; {Apparently need to restore} SetWindowLongPtr (Form1.Handle,GWLP_HWNDPARENT, SaveAppHandle); {$ENDIF} Form1.Free; EnableWindow(AppHandle,true); SetWindowPos( AppHandle, HWND_TOP, 0,0,0,0, SWP_NOSIZE or SWP_NOMOVE or SWP_FRAMECHANGED); end; except on E:Exception do begin // WriteLn(E.Message); end; end; end; exports {$IFDEF DARWIN} {OS X} RunForm name '_RunForm', {For use with LoadLibrary} {$ENDIF} RunForm; end. |
|
Note that I posted above code while using Lazarus-0.9.31-30932-fpc-2.5.1-20110527-win64.exe and modal forms in dll didn't work after only calling form.showmodal. The form was shown and waited for input but it didn't have a parent form and wasn't modal. So I had to reparent: SetWindowLongPtr(Form1.Handle,GWLP_HWNDPARENT, AppHandle); and disable the parent window. EnableWindow(AppHandle,false); After the form closed the process was reversed, in right order. |
|
Also if DLL form is NOT modal you only need to reparent but like this: SetWindowLongPtr(Form1.Handle,GWLP_HWNDPARENT, AppHandle); SetWindowPos( Form1.Handle, AppHandle, 0,0,0,0, SWP_NOSIZE or SWP_NOMOVE or SWP_FRAMECHANGED); Form1.Show; Result := True; finally {$IFNDEF LCL} //Application.Handle := SaveAppHandle; {Apparently need to restore} {$ENDIF} end; ----------- Make sure the DLL form frees the memory: procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; |
|
0016611 also relates to the problem and contains the solution of showing form from DLL in X-platform manner. |
|
It is possible in Lazarus 1.7. See http://wiki.freepascal.org/Form_in_DLL [^] Everybody is welcome to donate bounties (if still interested) to Lazarus ;) |
|
Also if DLL form is NOT modal you only need to reparent but like this: SetWindowLongPtr(Form1.Handle,GWLP_HWNDPARENT, AppHandle); SetWindowPos( Form1.Handle, AppHandle, 0,0,0,0, SWP_NOSIZE or SWP_NOMOVE or SWP_FRAMECHANGED); Form1.Show; Result := True; finally {$IFNDEF LCL} //Application.Handle := SaveAppHandle; {Apparently need to restore} {$ENDIF} end; ----------- Make sure the DLL form frees the memory: procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; http://bit.ly/346ObgY |
Date Modified | Username | Field | Change |
---|---|---|---|
2006-07-19 21:55 | Phil | New Issue | |
2006-07-19 21:55 | Phil | File Added: LCLinDLL.zip | |
2006-08-07 17:37 | Christian Budde | Note Added: 0008621 | |
2006-08-08 02:35 | Christian Budde | Note Added: 0008628 | |
2006-08-08 02:36 | Christian Budde | Note Edited: 0008621 | |
2006-08-08 03:34 | Christian Budde | Note Edited: 0008628 | |
2006-08-08 05:32 | Christian Budde | Note Edited: 0008628 | |
2006-08-08 05:34 | Christian Budde | Note Added: 0008629 | |
2006-08-08 17:33 | Christian Budde | Note Added: 0008630 | |
2006-08-09 15:01 | Christian Budde | Note Edited: 0008630 | |
2006-08-09 17:00 | Christian Budde | Note Edited: 0008630 | |
2006-08-09 17:07 | Christian Budde | Note Edited: 0008630 | |
2006-12-30 19:29 | Jonas Maebe | Relationship added | related to 0007240 |
2006-12-30 19:29 | Jonas Maebe | Relationship added | related to 0007244 |
2007-01-02 02:02 | Marc Weustink | Project | FPC => Lazarus |
2007-01-02 02:07 | Marc Weustink | LazTarget | => - |
2007-01-02 02:07 | Marc Weustink | Widgetset | => GTK |
2007-01-02 02:07 | Marc Weustink | Note Added: 0010611 | |
2007-01-02 02:07 | Marc Weustink | Severity | block => major |
2007-01-02 02:07 | Marc Weustink | Category | Compiler => LCL |
2007-01-02 02:07 | Marc Weustink | Product Version | 2.1.1 => |
2007-01-02 02:16 | Marc Weustink | LazTarget | - => post 1.0 |
2007-01-02 10:58 | Vincent Snijders | Status | new => acknowledged |
2007-07-31 22:37 | Christian Budde | Note Added: 0013903 | |
2007-08-29 13:28 | Marco van de Voort | Note Added: 0014311 | |
2007-11-27 14:31 | Felipe Monteiro de Carvalho | Relationship added | duplicate of 0007181 |
2007-11-27 15:08 | Felipe Monteiro de Carvalho | Relationship added | has duplicate 0001866 |
2009-01-29 22:34 | Oleg Sharonov | Note Added: 0024869 | |
2009-01-29 23:05 | Phil | Note Added: 0024871 | |
2009-01-30 09:26 | Oleg Sharonov | Note Added: 0024880 | |
2009-11-17 19:09 | Vincent Snijders | Relationship added | related to 0015126 |
2011-05-29 04:41 | Edin | Note Added: 0048694 | |
2011-05-29 04:50 | Edin | Note Added: 0048695 | |
2011-05-29 04:51 | Edin | Note Edited: 0048695 | |
2011-05-29 11:33 | Edin | Note Edited: 0048694 | |
2011-05-29 11:45 | Edin | Note Edited: 0048695 | |
2011-05-29 11:57 | Edin | Note Edited: 0048695 | |
2011-05-29 12:08 | Edin | Note Added: 0048701 | |
2011-06-01 11:38 | Anton Kavalenka | Note Added: 0048739 | |
2012-02-04 12:05 | Zeljan Rikalo | LazTarget | post 1.0 => 1.2 |
2012-12-26 15:49 | Bart Broersma | Relationship replaced | has duplicate 0007181 |
2014-01-14 15:16 | Martin Friebe | LazTarget | 1.2 => 1.4 |
2014-07-01 20:16 | Juha Manninen | Relationship added | related to 0026439 |
2014-09-20 18:31 | Juha Manninen | Relationship added | has duplicate 0026543 |
2014-09-21 01:31 | Juha Manninen | Relationship added | related to 0016611 |
2014-10-01 10:22 |
|
Tag Attached: dll | |
2014-10-01 10:22 |
|
Tag Attached: library | |
2015-05-07 06:46 | Juha Manninen | LazTarget | 1.4 => - |
2015-10-12 22:39 | Juha Manninen | Relationship added | related to 0028821 |
2015-10-18 19:00 | Juha Manninen | Relationship replaced | has duplicate 0028821 |
2016-05-11 00:13 | Ondrej Pokorny | Note Added: 0092509 | |
2016-05-11 00:13 | Ondrej Pokorny | Status | acknowledged => resolved |
2016-05-11 00:13 | Ondrej Pokorny | Resolution | open => fixed |
2016-05-11 00:13 | Ondrej Pokorny | Assigned To | => Ondrej Pokorny |
2016-05-11 00:25 | Ondrej Pokorny | Relationship added | has duplicate 0020320 |
2019-10-28 09:39 | Pit | Note Added: 0118890 |