Problem with Splash Screen in Lazarus app - delphi

I am porting a Delphi application to FPC/Lazarus and this application shows info in splash screen. When unit has initialization section then this initialization section calls something like:
Splash.Info(unit_name)
This works in Delphi, but when I compiled this using FPC/Lazarus then I got exception when I create form with splash screen:
Failed to create win32 control, error 1407 : Cannot find window class
I found, that forms can be created after Application.Initialize; was called, so my workaround is to create splash form when ScreenInfo.Initialized=true. It works, but does not show all info. Is there any way to show splash form from unit initialization section, before Application.Initialize;?

Apparantly the FPC/Lazarus implementation of the VCL differs enough from the Delphi VCL to not allow form initialization before the Application object has been initialized.
So the best you can do to make it work in both Delphi and FPC/Lazarus is either
Delay the initialization until you are sure that both the Delphi VCL and FPC/Lazarus VCL are ready for it
Duplicate your code with conditional defines to generate optimum implementations for both Delphi VCL and FPC/Lazarus VCL
--jeroen

In SplashScreen initialization code that is called for every string I want to show on this splash I finished with:
...
{$IFDEF FPC}
if not ScreenInfo.Initialized then
exit;
{$ENDIF}
if not splash_inititialized then begin
SplashScreen := TSplashScreen.Create(Application);
splash_inititialized := true;
...

Related

Property "ofOverwritePrompt" for TSaveDialog does not work when VCL Styles are used in Delphi 10.1 Berlin

Create a new VCL Forms application
On the main form add a Tbutton and a TSaveDialog
Set "ofOverwritePrompt" to True in properties for the SaveDialog1
Use:
procedure TForm1.Button1Click(Sender: TObject);
begin
SaveDialog1.Execute();
end;
Run the app. Press the button to execute the save dialog. Try to save to a file that already exists.
A message box appears if you want to replace the file. Press cancel. All fine so far. Close the app.
Go to Project/Options/Application/Appearance and select a Custom style (e.g. Amakrits). Set Amakrits as the default style.
Run the app as in #5 above. Only a small bit of the message box will be shown. You will have to press Enter to be able to continue.
(Using a TFileSaveDialog will give the same result)
If I compile and run the app using Delphi XE8 it will be ok since the save dialog window seems to use the default windows style even if another style is chosen.
Edit:
I have Windows 10 pro. Source compiled as win32 with Delphi 10.1 Berlin.
The replace message box is partly hidden. Only a small top left part is shown, see figure.
And here it is compiled with XE8 win32:
Ps. I am using the default 100% scale factor.
Compiling with win64 (Delphi 10.1 Berlin) seems to be ok:
So, compiling to win32 does not work for me, but 64-bit will. Any clues?
Edit: Trying with "GetSaveFileName(OFN)" will also not work for me in win32 (win 64 is ok):
You can avoid this issue using the dialog styling code of the VCL Styles Utils project.
Just Add these units to your project.
uses
Vcl.Styles.Utils.Menus, //Popup and Shell Menus (class #32768)
Vcl.Styles.Utils.Forms, //dialogs box (class #32770)
Vcl.Styles.Utils.StdCtrls, //buttons, static, and so on
Vcl.Styles.Utils.ComCtrls, //SysTreeView32, SysListView32
Vcl.Styles.Utils.ScreenTips, //tooltips_class32 class
Vcl.Styles.Utils.SysControls,
Vcl.Styles.Utils.SysStyleHook;
{$R *.dfm}
procedure TForm26.Button1Click(Sender: TObject);
begin
UseLatestCommonDialogs := false;
SaveDialog1.Execute();
end;
I cannot confirm the problem, and all looks well here, (32 bit executalbe, themed with Amakrits, compiled with 10.1 Berlin, on Windows 7, 100% scaling) but you could try this:
uses ... Winapi.CommDlg;
...
var
OFN: TOpenFileName;
begin
FillChar(OFN, SizeOf(OFN), 0);
OFN.lStructSize := SizeOf(OFN);
OFN.nMaxFile := MAX_PATH;
OFN.Flags := OFN_OVERWRITEPROMPT or OFN_HIDEREADONLY or OFN_ENABLESIZING or OFN_EXPLORER;
GetSaveFileName(OFN);
end;
The result is an Amakrits-themed, new Explorer-like save dialog, which works fine (for me). Only the two round, blue "back" and "forth" (<- and ->) buttons at the top left of the dialog look a little weird.
But I did not try this with custom scaling settings (e.g. Medium 125% in the Control Panel -> Display panel, etc.). I think this could influence such things.
Update
I just tried to use SaveDialog1 (commenting out the OFN code above) with custom Display scaling (125%). All looked fine, so that is not it. Also when I use the OFN code, all looks fine (actually, better, i.e. no XP style dialog, but a real Explorer-like dialog instead).
If I set "Enable High-DPI" to true in Project/Options/Application it will work (replace box properly displayed). Disabling it will cause the problem (both in win32 and win64).
For the record, I had exactly the same problem (Delphi 10.1 Berlin, compiling on Windows 10 64 bit, 100% screen settings, compiled for 32 bit target). Enabling or disabling High-DPMI awareness didn't help.
A workaround is to disable styles for dialog boxes before executing the TSaveDialog (or TOpenDialog) like this:
TStyleManager.SystemHooks := TStyleManager.SystemHooks - [shDialogs];
The file dialog itself will still be themed. You will get standard Windows-style message boxes in case an overwrite prompt (or create prompt) pops up, but they will be large enough for the user to read and click them. After the file dialog has finished, you can enable styled dialogs again by re-adding shDialogs to SystemHooks if needed.

Form appears after 'Application.CreateForm' step

I am working on a project in delphi 2007 (CodeGear RAD Studio).
There are couple of forms in the application. Thouse forms are created as follows:
program MyProgram;
uses
Forms,
uMain in 'Source\uMain.pas' {MainForm},
uSettings in 'Source\uSettings.pas' {fSettings};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.CreateForm(TSettings, Settings);
Application.Run;
end.
the problem is, that on line Application.CreateForm(TSettings, Settings); Settings form appears (not modal). And the question is why it is happening?.
I know that it is probably not enough information, but I am ready to provide some, if it is needed.
P.S. I am currently re-wrighting programm logic so settings form will be created only before it is about to appear, and after that delete it. Still, I would like to know the answer to this question.
Your settings form's Visible property is set to true at design time, and thus it appears as soon as it's created.

Add intellimouse support to a TMemo or TRichEdit component

How i can add intellimouse support to a TMemo or TRichEdit component
i am using Delphi XE
You must set the ScrollBars property to ssHorizontal, ssVertical or ssBoth and add the IMouse unit to your project.
UPDATE
To avoid the memory leak caused by the IMouse unit you must add this code before you application exit (for example in the finalization part of your main unit).
if Assigned(Mouse.PanningWindow) then
Mouse.PanningWindow := nil;

Automation object leaks memory (TConnectionPoints)

I have an automation object with event support that leaks memory. The FConnectionPoints which comes with the generated source is never freed. When I manually add FConnectionPoints.Free in the destructor, the leak goes away.
I am on Delphi 7, using a FastMM BorlandMM.dll and FastMM_Fulldebugmode.dll.
Steps to reproduce:
Start a new ActiveX Library project
Add a new Automation Object: Name = TestObject; Check "Generate Event support code"
Open the TypeLibrary, add a method to ITestObject, add an event to ITestObjectEvents
Refresh, code will be generated.
Add ShareMem as the first unit in your .dpr file
Save, compile and register this ActiveX Server (Run menu)
Start a new Application project
Put ShareMem as the first unit in your .dpr file
Import Type Library unit: create the unit from the dll you've just created in step 6, and check "Generate Component Wrapper"
In your FormCreate add the following code:
code:
var
lTest: TTestObject;
begin
lTest := TTestObject.Create(nil);
try
lTest.ConnectKind := ckNewInstance;
lTest.Connect;
lTest.Disconnect;
finally
lTest.Free;
end;
end;
Now compile, run and close this application. A memoryleak will be reported.
Question:
Is this a bug in the Delphi code template, am I doing someting wrong, or is it intended to free FConnectionPoints yourself (the help doesn't mention it)?
I don't fully understand the question as I never worked with automation objects but as far as I can see IConnectionPoint is an interface. Interfaces in Delphi are reference-counted (if the implementation inherits from TInterfacedObject, TContainedObject or TAgreggatedObject or implements _AddRef and _Release accordingly), so there should be no memory leak.
For more information on interfaces look at this article.
This chapter from the Delphi Language Guide could help too.
I found this issue to be reported in Quality Central report #1480.
A Sysop asked me to create a new report so I did: report #81288.
This also answers my question: it is a bug in the code template.

Empty main form in GUI app converted from Delphi to Lazarus

I have converted my 2 GUI apps from Delphi to Lazarus.
Both apps compile for Win32 platform, i386 and with GUI.
Main form were converted using Lazarus tool and can be edited from IDE.
But when I run such application main form does not appear, only blank form without any controls.
I tried to debug this. It runs all code in initialization sections,
and runs code from .lpr project, but something wrong happens in CreateForm() because
it doesn't run code in the main form OnCreate event. In event log I can see all
texts I write to it with '<App.Run' appearing after I close this empty form.
Code in .lpr project:
Application.Initialize;
AddToEventLogInfo('App.CreateForm');
Application.CreateForm(TfrmTst, frmTst);
AddToEventLogInfo('App.Run>');
Application.Run;
AddToEventLogInfo('<App.Run');
I checked that I am able to create simple GUI apps from the Lazarus, but both converted GUI
apps do not work as expected. What can be wrong? Have I missed something?
Maybe one of many warnings and hints Lazarus write is important?
When I run my app Lazarus writes this:
windres: warning: 14: "MAINICON": 1045: duplicate value
windres: warning: 16: 1: 1045: duplicate value
Project "Tst_fpc" successfully built. :)
EDIT:
Lazarus conversion tool converted .dfm -> .lfm, but has some problems with .pas file. I had to manually:
add Lazarus units to uses:
uses
{$IFDEF FPC}
LCLIntf, LResources,
{$ENDIF}
Conditional compile Delphi form {$R *.dfm}:
{$IFNDEF FPC}
{$R *.dfm}
{$ENDIF}
Add .lrs resource in initialization code:
initialization
{$IFDEF FPC} {$i myunit.lrs} {$ENDIF}
I suspect that the mainform unit (I assume it is called utest) doesn't have a {$I utest.lrs} in its initialization section. The .lrs is the lazarus resource file, created from the lfm (dfm) in delphi.
The empty form is the form of for the current project as you used the convert Delphi project from tools which means the current project is active.
Try this:
On the project option close the current project.
On the small main window named as project wizard, use the convert Delphi project option.
I'm sorry I can't give you a straight answer. From what I understand there's a problem a problem with the resource file. In delphi that's the *.res, I don't know what they look like in Lazarus. Use a program like resedit, http://www.resedit.net/, to open the resource file. I tried it and found a "folder" Icon where there was a post MAINICON. I'm guessing you have two. In that case remove one of them.

Resources