I am having one Delphi XE2 project to show scrolling text. My code is as follows :
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Caption := 'This is right scrolling text ';
Timer1.Enabled := true;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
S: String;
begin
S := Label1.Caption;
S := S[Length(S)] + Copy(S, 1, Length(S) - 1);
Label1.Caption := S;
end;
end.
Using the following code the text scrolls perfectly in 2d along to Y axis.
How to scroll text in Sinusoidal Wave ?
Angus Johnson's excellent GR32_Text extension to the fine graphics32 library appears to do what you need. The demos that you can download from the link above show just the effect you are asking for. All that remains is for you to animate the text in a paint box or similar control.
Related
Delphi MDIChild windowState problem
I have a delphi project with a MDI and childs. When I created a new child form, this occupies perfctly a reserved space on main form (child wsMaximized).
But when a create another child form (without closed first child), the first child "lost a wsMaximized state".
Resume: I need the child forms maximized every time, but when second child is opened, the "windowstate" another childs is changed.
First child:
procedure TfrmPrincipal.PosicionarForm(AForm: TForm);
var
Rect: TRect;
begin
GetWindowRect(Application.MainForm.ClientHandle, Rect);
InflateRect(Rect, -2 * GetSystemMetrics(SM_CXBORDER),
-2 * GetSystemMetrics(SM_CYBORDER));
OffsetRect(Rect, -Rect.Left, -Rect.Top);
AForm.BoundsRect := Rect;
end;
procedure TfrmPrincipal.actCadastroFornecedorExecute(Sender: TObject);
begin
frmCadastroFornecedor := TfrmCadastroFornecedor.Create(Application);
PosicionarForm(frmCadastroFornecedor);
frmCadastroFornecedor.Show;
svSub.Visible := False;
SV.Opened := False;
end;
Secound child:
procedure TfrmPrincipal.actCadastroProdutosExecute(Sender: TObject);
begin
frmCadastroProduto := TfrmCadastroProduto.Create(Application);
PosicionarForm(frmCadastroProduto);
frmCadastroProduto.Show;
svSub.Visible := False;
SV.Opened := False;
end;
EDIT:
I created a new project, have 3 forms. The code is very simple, but this behavior continues.
Main FORM:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus;
type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
screen11: TMenuItem;
screen21: TMenuItem;
procedure screen11Click(Sender: TObject);
procedure screen21Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
unit2, unit3;
{$R *.dfm}
procedure TForm1.screen11Click(Sender: TObject);
begin
form2 := tform2.Create(Application);
form2.Show;
end;
procedure TForm1.screen21Click(Sender: TObject);
begin
form3 := tform3.Create(Application);
form3.Show;
end;
end.
Child 1:
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TForm2 = class(TForm)
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
end.
Child 2:
unit Unit3;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TForm3 = class(TForm)
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
{$R *.dfm}
procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
end.
After some trial and error (once again an example of how important a complete, minimal, reproducible, example is) I was able to reproduce the error you ask about. If you had included the the .dfm files, the actual problem had been clear much sooner.
Now, to the problem that the WindowState of the forms change from wsMaximized to wsNormal after deletion of one of the childforms.
This happens when you have removed biMaximise from BorderIcons for forms Form2 and Form3
Cure: Let BorderIcons.biMaximise be selected.
I also suggest you remove PosicionarForm(AForm: TForm); from the main form. It doesn't appear to do anything useful.
I have a crystal report (.RPT File) which has been created by a POS system, I need to get all the records from this report into a database so I can use it in my program. The problem is that it is grouped and have headers and footers, when exporting jut like this it exports a lot of nonsense to the ODBD database. I would like to suppress all Groups and headers and only export the details. In crystal designer I can do this by clicking on each group and suppressing them. I need to do this from within Delphi. See my working code for viewing the data, and currently exporting everything to Excel.
`unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.OleServer,
CrystalActiveXReportViewerLib14_TLB, Vcl.OleCtrls, OleAuto,
CrystalReportViewerExportLib_TLB;
type
TForm2 = class(TForm)
CrystalRpt: TCrystalActiveXReportViewer;
Button1: TButton;
Button2: TButton;
CrystalExport: TCrystalReportExport;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
var
oApp : variant ;
begin
oApp := CreateOleObject('CrystalRuntime.Application') ;
crystalrpt.ReportSource := oApp.OpenReport('c:\guess.rpt',1);
{crystalrpt.ShowGroup('Group Header #1') ;}
crystalrpt.ViewReport ;
end;
procedure TForm2.Button2Click(Sender: TObject);
var
cry : TCrystalActiveXReportViewer;
oRpt, oApp : variant;
i : integer;
begin
//Export the report to a file
oApp := CreateOleObject('CrystalRuntime.Application');
oRpt := oApp.OpenReport('c:\guess.rpt',1);
oRpt.ExportOptions.FormatType := 29; //excel 8
oRpt.ExportOptions.DiskFileName := 'c:\output.xls';
oRpt.ExportOptions.DestinationType := 1; //file destination
oRpt.ExportOptions.
//Export(False) => do NOT prompt.
//Export(True) will give runtime prompts for export options.
oRpt.Export(false);
end;
end.`
Update:
This question escalated to a new/related question which was fortunately solved by #RemyLebeau here.
So, instead of reading below, you should go directly to Major flaw - Radio buttons are not correctly set while the form is invisible
Thanks Remy
I have two form. When I click a radiobtn, I want to hide one form and show the second one.
Hide Form1 and show Form2:
procedure TForm1.RadioButton2Click(Sender: TObject);
begin
Form2.Visible:= TRUE;
Form1.Visible:= FALSE;
end;
In Form2 I press a button to 'return' to Form1:
procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.RadioButton1.Checked:= TRUE;
Form1.Visible:= TRUE; <--- this will 'magically' put the RadioButton1 back to false
end;
However, I get this error when I try to make Form1 visible:
Project Tester.exe raised exception class EInvalidOperation with
message 'Cannot change Visible in OnShow or OnHide'
Putting a breakpoint in RadioButton2Click I find out that RadioButton1 was magically rechecked during Form1.Visible:= TRUE (during TCustomForm.SetVisible more exactly).
Why is the RadioButton2 'magically' checked during SetVisible?
unit Unit1;
INTERFACE
USES
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, System.Actions, Vcl.ActnList, Vcl.StdCtrls;
TYPE
TForm1 = class(TForm)
GroupBox1: TGroupBox;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
procedure RadioButton2Click(Sender: TObject);
procedure RadioButton1Click(Sender: TObject);
private
public
end;
VAR
Form1: TForm1;
IMPLEMENTATION {$R *.dfm}
USES Unit2;
procedure TForm1.RadioButton1Click(Sender: TObject);
begin
Caption:= '1';
end;
procedure TForm1.RadioButton2Click(Sender: TObject);
begin
Caption:= '2';
Form2.Visible:= TRUE;
Form1.Visible:= FALSE;
end;
end.
-
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
VAR
Form2: TForm2;
IMPLEMENTATION {$R *.dfm}
USES Unit1;
procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.RadioButton1.Checked:= TRUE;
Form1.Visible:= TRUE;
end;
end.
The workaround (not the final fix) is to do the changes to the GUI (form1) AFTER you make it visible!
Update!
The bug is related to the TabOrder property!
Details
Direct references from one form to fields of another is bad design and I highly advice you to change this. But anyway, I made two forms: first with two radiobutton, second with a button. Handlers:
{ For both radiobuttons }
procedure TForm1.RadioButtonClick(Sender: TObject);
begin
Form1.Visible := RadioButton1.Checked;
Form2.Visible := RadioButton2.Checked;
end;
{ For button }
procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.RadioButton1.Checked := true;
end;
It works fine, without any remark. Delphi 10.1 Berlin.
I have an application with multiple forms and a separate taskbar button for each form.
Let's say form2 displays an OpenDialog, I click away to another maximized application covering the full screen area, then I go back to form2 by selecting it's taskbar button. Voila! The OpenDialog is hidden behind the other application I selected, and I have to click on the now non-accessible form2 to bring the dialog back to the front. This is really annoying and may confuse the user.
Here is some code to illustrate the issue:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses Unit2;
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
end;
end.
________________
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm2 = class(TForm)
OpenDialog1: TOpenDialog;
Button1: TButton;
procedure CreateParams(var Params: TCreateParams); override;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
OpenDialog1.Execute;
end;
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
Params.WndParent := GetDesktopWindow;
end;
end.
Is it possible maybe to get the handle of the visible opendialog? It used to be possible, but with the new Vista style OpenDialog if I trap OnDialogShow the OpenDialog reverts back to the old style which is a no go for me now.
Any ideas?
TOpenDialog.Execute() has an optional parameter that lets you specify a parent window that the dialog is not allowed to fall behind:
procedure TForm2.Button1Click(Sender: TObject);
begin
OpenDialog1.Execute(Self.Handle);
end;
If you do not specify a parent window, the active Form's window is used if Application.ModalPopupMode is not pmNone, otherwise the Application.MainForm window is used instead.
So I've figured out how to bring the dialog to the front, but there is still one problem: the focus is on Form2, not the dialog. If someone can tell me how to put the focus on the opendialog instead of Form2 and post it as an answer, I'll accept it.
Here are the code excerpts to add to the original:
type
TForm1 = class(TForm)
private
procedure WMActivate(var Msg: TWMActivate); message WM_ACTIVATE;
public
{ Public declarations }
end;
var
Form1: TForm1;
DialogFormHandle: HWnd;
...
procedure TForm1.WMActivate(var Msg: TWMActivate);
begin
inherited;
if DialogFormHandle <> 0 then
begin
BringWindowToTop(DialogFormHandle);
exit;
end;
end;
...
procedure TForm2.Button1Click(Sender: TObject);
begin
try
DialogFormHandle := Handle;
OpenDialog1.Execute(Handle);
finally
DialogFormHandle := 0;
end;
end;
Thanks!
Im trying to make a FMX form in a dll, after about 17 hours (of trying diffrent approches) i got it working, except i get a exception trying to unload the dll. I have no idea how to make it work, maybe someone could help me and point out what im doing wrong?
side note:
i cant have a FMX form in my VCL application becouse of the AA drawing, i just need it on my text while drawing on a canvas and while having a FMX form on a VCL application, i dont get that cleartype on text :( im trying to make a some sort of OSD/HUD.
Project showing my problem:
exe unit1.pas
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
unitLoadDLL, Winapi.GDIPOBJ;
procedure TForm1.Button1Click(Sender: TObject);
begin
showme();
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
closeme();
end;
end.
exe unitLoadDll.pas
unit unitLoadDLL;
interface
uses Windows, Dialogs;
type
TShowme = procedure();
TCloseme = procedure();
var
showme : TShowme = nil;
closeme : TCloseme = nil;
DllHandle : THandle;
implementation
initialization
if DllHandle = 0 then begin
DllHandle := LoadLibrary('C:\Users\Ja\Desktop\dupa\dll\Win32\Debug\Project1.dll');
if DllHandle > 0 then begin
#showme := GetProcAddress(DllHandle,'showme');
#closeme := GetProcAddress(DllHandle,'closeme');
end
else begin
MessageDlg('Select Image functionality is not available', mtInformation, [mbOK], 0);
end;
end;
finalization
if DLLHandle <> 0 then
FreeLibrary(DLLHandle);
end.
dll project1.dpr
library Project1;
uses
FMX.Forms,
System.SysUtils,
System.Classes,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
procedure showme(); stdcall export;
begin
TForm1.showme;
end;
procedure closeme(); stdcall export;
begin
TForm1.closeme;
end;
exports
showme, closeme;
begin
end.
dll unit1.pas
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs;
type
TForm1 = class(TForm)
Label1: TLabel;
private
{ Private declarations }
public
class procedure showme();
class procedure closeme();
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
class procedure TForm1.showme();
begin
Form1 := TForm1.Create(Application);
Form1.Show;
end;
class procedure TForm1.closeme();
begin
Form1.Free;
end;
end.
EDIT (FIX):
All answers ware helpfull, but what i've done is, that the GDI+ was shutdown BEFORE the dll unload... that appear's to be the problem.
new unitLoadDll.pas
unit unitLoadDLL;
interface
uses Windows, Dialogs;
type
TShowme = procedure();
TCloseme = procedure();
var
showme : TShowme = nil;
closeme : TCloseme = nil;
DllHandle : THandle;
function LoadLib : Boolean;
procedure UnloadLib;
implementation
function LoadLib : Boolean;
begin
if DllHandle = 0 then begin
DllHandle := LoadLibrary('C:\Users\Ja\Desktop\dupa\dll\Win32\Debug\Project1.dll');
if DllHandle > 0 then begin
#showme := GetProcAddress(DllHandle,'showme');
#closeme := GetProcAddress(DllHandle,'closeme');
end
else begin
MessageDlg('Select Image functionality is not available', mtInformation, [mbOK], 0);
end;
end;
Result := DllHandle <> 0;
end;
procedure UnloadLib;
begin
if DLLHandle <> 0 then begin
FreeLibrary(DLLHandle);
DllHandle := 0;
end;
end;
initialization
LoadLib;
finalization
UnloadLib;
end.
new unit1.pas
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Winapi.GDIPOBJ;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
unitLoadDLL;
procedure TForm1.Button1Click(Sender: TObject);
begin
showme();
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
closeme();
end;
end.
in unit1.pas i moved the Winapi.GDIPOBJ to "uses" just after interface directive, and it worked...
Thank you all for your answers! See you soon! very soon...
Does it help if you import sharemem on both sides?
You are not using packages, so both sides probably have an own instance all RTL state, as well as VMT tables (though that is only a problem with certain IS and AS cases). And the memory manager is RTL state :-)