Solution to Printing Crystal Reports XI Forms in Delphi XE3 - delphi

After suffering through the same problems as others did, I came up with this solution to previewing/printing Crystal Reports XI reports. This borrows a few lines for the login sequence. I still can't find anything in the *TLB.pas files that allows me to login to the server directly rather than running down through the list of tables. Anyway, here's what I have at this point. Hope it helps someone !
Unit CrystalReports;
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.OleCtrls, ActiveX, ComObj, Data.DB, Data.Win.ADODB,
CrystalActiveXReportViewerLib11_TLB, Vcl.OleServer, CrystalReportsControllersLib_TLB;
type
TCrystalReportForm = class(TForm)
CRV: TCrystalActiveXReportViewer;
procedure DisplayReport;
private
{ Private declarations }
public
{Public declarations }
ReportName : WideString;
ReportCaption : String;
ReportSelectionFormula : WideString;
end;
var
CRXIRuntime : Variant;
implementation
{$R *.dfm}
procedure TCrystalReportForm.DisplayReport;
var
CrystalReport : variant;
i : integer;
begin
CrystalReport := CRXIRuntime.OpenReport(ReportName);
for i := 1 to CrystalReport.Database.Tables.Count do begin
CrystalReport.Database.Tables[1].ConnectionProperties.Item['User ID'] := 'user';
CrystalReport.Database.Tables[1].ConnectionProperties.Item['Password'] := 'password';
end;
CrystalReport.FormulaSyntax := 0;
Caption := ReportCaption;
CrystalReport.RecordSelectionFormula := ReportSelectionFormula;
CRV.Align := alClient;
CRV.ReportSource := CrystalReport;
WindowState := wsMaximized;
CRV.ViewReport;
ShowModal;
end;
begin
CRXIRuntime := CreateOleObject('CrystalRuntime.Application');
end.

Related

Delphi IdTCPClient.connect Hanging while threaded

I am trying to run 8 threads making IdTCPClient repeatedly scanning a range of IP. When these threads are running, the main form is hanging, lagging. The "IdTCClient.connect" is the issue. Is there a way to fix that ?
unit Unit3;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TTcpThread = class(TThread)
Idx: word;
procedure Execute; override;
end;
TForm3 = class(TForm)
procedure FormShow(Sender: TObject);
private
public
end;
var
Form3: TForm3;
implementation
uses IdTCPClient;
{$R *.dfm}
procedure TTcpThread.Execute;
begin
for var i := Idx*8 to (Idx*8) + (8-1) do // 8 IP per Thread
begin
var TCP := TidTCPClient.Create(nil);
TCP.Host := '192.168.1.' + i.ToString;;
TCP.Port := 9999;
TCP.ConnectTimeout := 500;
TCP.ReadTimeout := 1000;
try
TCP.Connect;
TCP.Disconnect;
except end;
TCP.Free;
end;
end;
procedure TForm3.FormShow(Sender: TObject);
begin
for var i := 0 to 32-1 do // 32 Threads
begin
var Thread := TTcpThread.Create(True);
Thread.Idx := i;
Thread.FreeOnTerminate := True;
Thread.Start;
end;
end;
end.
The mainform will freeze/lag while the threads are running

CEF4Delphi unit test not

I am testing a TFrame with CEF4Delphi component in it but I have issues when it comes to freeing up the TForm containing the TFrame and the relevant CEF4Delphi components.
The following is a Minimal Example
program MyTFrameExample;
{
Delphi DUnit Test Project
-------------------------
This project contains the DUnit test framework and the GUI/Console test runners.
Add "CONSOLE_TESTRUNNER" to the conditional defines entry in the project options
to use the console test runner. Otherwise the GUI test runner will be used by
default.
}
{$IFDEF CONSOLE_TESTRUNNER}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
madExcept,
madLinkDisAsm,
madListHardware,
madListProcesses,
madListModules,
DUnitTestRunner,
Vcl.Forms,
WinApi.Windows,
uCEFApplication,
SSFrame in '..\..\SS\SSFrame.pas' {SSFrm: TFrame},
TestSSFrame in '..\..\Test\TestSSFrame.pas';
{*.RES}
{$I cef.inc}
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.SingleProcess := True;
if GlobalCEFApp.StartMainProcess then
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
DUnitTestRunner.RunRegisteredTests;
Application.Run;
end;
GlobalCEFApp.Free;
end.
unit TestSSFrame;
{
Delphi DUnit Test Case
----------------------
This unit contains a skeleton test case class generated by the Test Case Wizard.
Modify the generated code to correctly setup and call the methods from the unit
being tested.
}
interface
uses
TestFramework,
System.SysUtils,
Vcl.Graphics,
uCEFChromium,
Winapi.Windows,
System.Variants,
uCEFInterfaces,
uCEFChromiumWindow,
Vcl.Dialogs,
Vcl.Controls,
uCEFWindowParent,
Vcl.Forms,
Winapi.Messages,
SSFrame,
System.Classes;
type
// Test methods for class TSSFrm
TestTSSFrm = class(TTestCase)
strict private
FSSFrm: TSSFrm;
FMainForm: TForm;
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestChromium1AfterCreated;
end;
implementation
procedure TestTSSFrm.SetUp;
begin
Application.CreateForm(TForm, FMainForm);
FSSFrm := TSSFrm.Create(FMainForm);
FSSFrm.Parent := FMainForm;
FSSFrm.Visible := True;
FSSFrm.Align := alClient;
FSSFrm.Chromium1.CreateBrowser(FSSFrm.ChromiumWindow1);
if not (FSSFrm.ChromiumWindow1.CreateBrowser) then
FSSFrm.Timer1.Enabled := True;
while FSSFrm.Chromium1.Initialized = False do
begin
Application.ProcessMessages;
end;
FMainForm.Show;
end;
procedure TestTSSFrm.TearDown;
begin
FMainForm.Free;
[enter link description here][1] FMainForm := nil;
end;
procedure TestTSSFrm.TestChromium1AfterCreated;
var
a: Boolean;
begin
if (FMainForm.Components[0] is TSSFrm) then
begin
a := (FMainForm.Components[0] as TSSFrm).IsGoogleSearchPageCreated;
CheckTrue(a);
end;
end;
initialization
// Register any test cases with the test runner
RegisterTest(TestTSSFrm.Suite);
end.
unit SSFrame;
interface
uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
uCEFWindowParent,
uCEFChromiumWindow,
uCEFInterfaces,
uCEFChromium,
Vcl.StdCtrls,
Vcl.ExtCtrls;
type
TSSFrm = class(TFrame)
Chromium1: TChromium;
ChromiumWindow1: TChromiumWindow;
Timer1: TTimer;
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
FIsGoogleSearchPageLoaded: Boolean;
FIsGoogleSearchPageCreated: Boolean;
public
{ Public declarations }
function IsGoogleSearchPageCreated: Boolean;
end;
implementation
{$R *.dfm}
procedure TSSFrm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
begin
FIsGoogleSearchPageLoaded := False;
FIsGoogleSearchPageCreated := True;
end;
function TSSFrm.IsGoogleSearchPageCreated: Boolean;
begin
Result := FIsGoogleSearchPageCreated;
end;
procedure TSSFrm.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
if not (ChromiumWindow1.CreateBrowser) and not (ChromiumWindow1.Initialized) then
Timer1.Enabled := True;
end;
end.
When I run TestTSSFrm.TestChromium1AfterCreated; the test pass but when it comes to close the test application then the application itself does not close completely and I have to reset it from the IDE manually. If I comment out the lines
FMainForm.Free;
FMainForm := nil;
then I have no issues with closing the test application but I have to close the form manually.
Where am I doing wrong?

How to get FileName and Directory of Windows Control Panels?

In Delphi, create a VCL Forms Application. Use the 64-bit Windows platform if you are on a 64-bit Windows.
Use the following code:
unit Unit1;
interface
uses
CodeSiteLogging,
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
procedure GetControlPanelItems;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Winapi.ShlObj, Winapi.ShellAPI, System.Win.ComObj;
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
GetControlPanelItems;
end;
procedure TForm1.GetControlPanelItems;
var
psfDeskTop: IShellFolder;
psfControl: IShellFolder;
pidControl: PITEMIDLIST;
pidChild: PITEMIDLIST;
pidAbsolute: PItemIdList;
pEnumList: IEnumIDList;
celtFetched: ULONG;
FileInfo: SHFILEINFOW;
ShExeInfo: SHELLEXECUTEINFO;
begin
OleCheck(SHGetDesktopFolder(psfDeskTop));
OleCheck(SHGetSpecialFolderLocation(0, CSIDL_CONTROLS, pidControl));
OleCheck(psfDeskTop.BindToObject(pidControl, nil, IID_IShellFolder, psfControl));
OleCheck(psfControl.EnumObjects(0, SHCONTF_NONFOLDERS or SHCONTF_INCLUDEHIDDEN or SHCONTF_FOLDERS, pEnumList));
while pEnumList.Next(1, pidChild, celtFetched) = 0 do
begin
pidAbsolute := ILCombine(pidControl, pidChild);
SHGetFileInfo(LPCTSTR(pidAbsolute), 0, FileInfo, SizeOf(FileInfo), SHGFI_PIDL or SHGFI_DISPLAYNAME or SHGFI_TYPENAME);
CodeSite.Send('TForm1.GetControlPanelItems: szDisplayName', FileInfo.szDisplayName);
// Exe-Info:
ZeroMemory(#ShExeInfo, SizeOf(ShExeInfo));
ShExeInfo.cbSize := SizeOf(ShExeInfo);
ShExeInfo.lpVerb := 'Open';
// control panel item's PIDL:
ShExeInfo.lpIDList := pidAbsolute;
ShExeInfo.nShow := SW_SHOWNORMAL;
ShExeInfo.fMask := SEE_MASK_IDLIST;
//ShExeInfo.lpFile := ???
//ShExeInfo.lpDirectory := ???
CodeSite.Send('TForm1.GetControlPanelItems: ShExeInfo.lpFile', ShExeInfo.lpFile);
CodeSite.Send('TForm1.GetControlPanelItems: ShExeInfo.lpDirectory', ShExeInfo.lpDirectory);
end;
end;
end.
This gets me the Display names of the control panels.
But how can I get the file-paths? (ShExeInfo.lpDirectory, ShExeInfo.lpFile)
As others mentioned here, it might be worthless to try getting file name of a certain applet binary as there can be more than one applet implemented in a single binary. For your overall task, dropped in your comment, creating shell shortcut links, simply use absolute ITEMIDLIST that you know in your loop, and set it to the created IShellLink object by the SetIDList method.

Delphi IdIcmpclient ping error 10040 xe5

These two days I start to write some codes for ping some other devices using Delphi XE5. To my pleasure, I find there's a component named IcmpClient can be used for ping. Here's the code, mostly from some web resource.
unit main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Samples.Spin,
Vcl.ExtCtrls, IdBaseComponent, IdComponent, IdRawBase, IdRawClient,
IdIcmpClient;
type
TfrmPing = class(TForm)
edtHost: TEdit;
btnPing: TButton;
ICMP: TIdIcmpClient;
Label1: TLabel;
Panel1: TPanel;
spnPing: TSpinEdit;
lstReplies: TListBox;
procedure btnPingClick(Sender: TObject);
procedure ICMPReply(ASender: TComponent; const ReplyStatus: TReplyStatus);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmPing: TfrmPing;
implementation
{$R *.dfm}
procedure TfrmPing.btnPingClick(Sender: TObject);
var
i: integer;
begin
ICMP.OnReply := ICMPReply;
ICMP.ReceiveTimeout := 1000;
btnPing.Enabled := False; try
ICMP.Host := edtHost.Text;
for i := 1 to spnPing.Value do begin
ICMP.Ping;
Application.ProcessMessages;
end;
finally btnPing.Enabled := True; end;
end;
procedure TfrmPing.ICMPReply(ASender: TComponent; const ReplyStatus: TReplyStatus);
var
sTime: string;
begin
// TODO: check for error on ping reply (ReplyStatus.MsgType?)
if (ReplyStatus.MsRoundTripTime = 0) then
sTime := '<1'
else
sTime := '=';
lstReplies.Items.Add(Format('%d bytes from %s: icmp_seq=%d ttl=%d time%s%d ms',
[ReplyStatus.BytesReceived,
ReplyStatus.FromIpAddress,
ReplyStatus.SequenceId,
ReplyStatus.TimeToLive,
sTime,
ReplyStatus.MsRoundTripTime]));
end;
end.
After solving the problem of Error #10013 (by giving the administrator privilege ), I met with the second error #10040.
According to one post here, some people said that happens after upgrading from xe3 to xe4, and Remy Lebeau said it was on fixing. But after a few months, we are still meeting with the errors with XE5.
Should I just abandon Indy 10 and look for some other way to PING, or waiting for the fixes?

FMX form in a DLL (firemonkey/delphi)

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 :-)

Resources