How work with Word and Excel in Delphi? - delphi

I use Delphi X10 and Word 2016 64-bit on Windows 10 64-bit.
I always used ComObj.
for example:
uses ComObj;
procedure TForm1.RzBitBtn1Click(Sender: TObject);
var Excel: variant; i, j: word;
begin
Excel := CreateOleObject('Excel.Application');
Excel.Workbooks.Open('file.xls');
for i := 1 to 5 do
for j := 1 to 5 do
StringGrid1.Cells[j, i] := Excel.Sheets[1].Cells[i, j].Text;
end;
But, i want to use autocompleate for Excel methods. I read what i should import type library, but i cant find type library file in my system.

This is quite easy to do, as long as the type libraries for Excel anmd Word are correctly registered.
Go to the OCX\Servers folder under your Delphi install and find Word2010.Pas. Add it to a new VCL project, and USE it in the main form's unit. Declare a form variable A: WordApplication on your main form.
With that done, you should be able to go to Form1's Form.Create, type
A.
and autocomplete should offer you the possibilities for WordApplication's methods and properties.
Now, open Word2010.Pas and find the section
// File generated on 2/20/2013 5:56:45 PM from Type Library described below.
// ************************************************************************ //
// Type Lib: c:\Program Files\Microsoft Office\Office14\msword.olb (1)
// LIBID: {00020905-0000-0000-C000-000000000046}
That tells you the name and location of the type library which was used to generate Word2010.Pas.
Now, unless you need to use some method/property that has been added to Word/Excel since the 2010 version, Word2010.Pas and Excel2010.Pas may be all you need. However, you can import the type library of a more recent version using Delphi and have it generate an import unit for it. Exactly how to do that depends on your Delphi version, but for Delphi Seattle. you simply go to Component | Import Component from the IDE main menu, then select Import type library in the pop-up and follow the wizard's prompts.
Once you've generated the import unit, obviously you simply USE it in your project instead of MSWord2010.
Btw, strictly speaking, there is no "Delphi X10", recent versions (since XE8) have been Seattle, Berlin and Tokyo.

Related

Lockbox 3 for Android with XE7 not working

I just found that lockbox 3.6.0 should support Android. However when i look in my palette i see that the codec only supports win32 and win64.
How can i make it work for my android apps also?
Im using Delphi XE7 and have already followed the installation instructions supplied in the package. For a windows app it works just fine.
You have two options:
(1) Run-time
You can always create the components at run-time. There is an example on the website on how to do it, and I copy a fragment of this example below. Just replace the ShowMessage() functions with whatever is appropriate ...
procedure EncryptAStream( Plaintext, Ciphertext: TStream);
var
Codec1: TCodec;
CryptographicLibrary1: TCryptographicLibrary;
begin
ShowMessage( 'Demonstration of How to Encrypt a Stream with TurboPower LockBox 3.');
Codec1 := TCodec.Create( nil);
CryptographicLibrary1 := TCryptographicLibrary.Create( nil);
Codec1.CryptoLibrary := CryptographicLibrary1;
Codec1.StreamCipherId := uTPLb_Constants.BlockCipher_ProgId;
Codec1.BlockCipherId := 'native.AES-256';
Codec1.ChainModeId := uTPLb_Constants.CBC_ProgId;
Codec1.Password := 'my utf-16le password';
// Codec1.Reset; Reset if you are continuing from a previous encryption operation.
Codec1.EncryptStream( Plaintext, Ciphertext);
// Codec1.Burn; Burn if you need to purge memory of sensitive data.
Ciphertext.Position := 0;
ShowMessageFmt(
'The ciphertext for AES-256 with CBC chaining'#13#10 +
' of plaintext ''banana'' (UTF-8 encoding),'#13#10 +
' and password ''my utf-16le password'' (UTF-16LE encoding),'#13#10 +
' prepended by 64 bit nonce, (being the IV),'#13#10 +
' and rendered for display in base64 is ...'#13#10 +
'%s', [Stream_to_Base64( Ciphertext)]);
Codec1.Free;
CryptographicLibrary1.Free;
end;
(2) Design-time
A little bit of tweaking is required to get the components onto the palette for Android. This will be done for you in the next version of TPLockbox 3 to be released, but for now, here is the procedure ...
Remove vcl, vclimg and dbrtl from the TPLB3 run-time requirements.
For the run-time package, add the Android target platform, and make it the active one. But of course, don't add this platform to the design-time package.
The binary product for the run-time should be named libTP_LockBox3_XE7.so, where XE7 is a place-marker for your compiler version.
Preface the declarations for the two components (TCodec and TCryptographicLibrary) with
[ComponentPlatformsAttribute( pidWin32 or pidWin64 or pidOSX32 or pidiOSSimulator or pidiOSDevice or pidAndroid)]
TCodec = class( TTPLb_BaseNonVisualComponent, ICryptographicLibraryWatcher,
{ etc. }
This is the key to the whole thing. The ComponentPlatformsAttribute attribute declares what platforms should the component be displayed for, on the palette. If not declared, I believe that the default is pidWin32 or pidWin64, but I cannot point to any official documentation to support this.
Recompile the run-time package. Remember that if your are compiling with MS-BUILD, on certain compiler versions, you need to save-all before you can successfully compile.
Go to the IDE Tools | Options and open the Library Path for the Android platform. Make sure that this path include the location of where you put the dcu files for the Android case. For example, on my installation it is ...
C:\Dev\TPLB\work-products\ephemeral\dcu\XE6\Android
You should physically check this directory. It should have a file named TPLB3.AES.dcu and another named TPLB3.AES.so for example.
Recompile and re-install the design-time package
Open your mobile project. Slap design-time components for TCodec and TCryptographicLibrary on your Android forms. Proceed as you would for a windows application.

Delphi Xe2 Package x64

Let's admit, I create new package in Delphi Xe2. I keep under a name "My". I add a simple component "MyComponent". I compile, I receive file Bpl in C:\Users\Public\Documents\RAD Studio\9.0\Bpl\My.bpl.
I add a platform "Win x64".
I compile, I receive C:\Users\Public\Documents\RAD Studio\9.0\Bpl\Win64\My.bpl.
...\Bpl\Win64\My.bpl to establish as new package does not give, writes "is not windows x32 applications".
The first is established normally and on a palette the component appears "MyComponent".
If to bring to are mute the index of a mouse will appear hint where it will be written, that it x32-compatible.
And at native component Delphi - at all x32-64 compatible.
Together with a disk to Xe2 there is a free disk with Free and Tral components if to put therefrom for example OverByteIcs or Ip*Works, that at them at all components will be 32-64х compatibility.
Questions:
1. How to establish the x64 the version package?
2. How to achieve, that the component had a compatibility 32-64, and not just 32?
P.S. Bad English language: ON
The Delphi IDE is 32 bit and so can only load 32 bit designtime packages. You can of course create 64 bit runtime packages.
Has earned, has understood!
We create empty package
We add the component, for example Button and it is specified what platforms for a component (the key moment are necessary!)
Example
unit GuButton;
interface
uses
System. SysUtils, System. Classes, Vcl. Controls, Vcl. StdCtrls;
type
[ComponentPlatformsAttribute (pidWin32 or pidWin64)] // !!!!!!!!!!!!!!!
TButtonGu = class (TButton)
private
{Private declarations}
protected
{Protected declarations}
public
{Public declarations}
published
{Published declarations}
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents (' Gu ', [TButtonGu]);
end;
We keep, we compile under x32. We add a platform x64 (in options should be registered, that directories under platforms different).
We compile under x64. We receive 2 BPL (as in the first question). We establish x32. We look - new component ButtonGu - 32-64 compatible was added.
Here I that wanted, all thanks.
In addition http://docwiki.embarcadero.com/RADStudio/en/64-bit_Cross-Platform_Application_Development_for_Windows

ActiveX controls with old Delphi versions

I'm testing a non visual ActiveX control based on a registered .ocx
which I import into Delphi using the provided wizard.
Then, I simply put the generated component on the main form of a new VCL application.
Under old Delphi versions (D5 and D2007), when i launch the application, this raise an AV
during the component initialization.
with Delphi 2009 : no problem, the application starts smoothly.
My questions are :
Are there known enhancements of ActiveX management in recent Delphi versions which
can explain this difference ?
Can I suspect a bug in the ActiveX control, or can I consider the origin of the
problem is from old Delphi versions ?
I need to use this component (if tests OK) in D2007.
Do you think that it is possible to correct the AV problem under D2007 by modifying the D2007 generated .tlb file (for example by trying to use the D2009 generated one)
PS: the ActiveX control is not named, because my question is a general question about Delphi and ActiveX, not about a specific ActiveX control.
Edit :
With D2007, the error (an Access Violation) appears during Application.CreateForm(TForm1, Form1);
and more specifically when the Olecontrol is created :
procedure TOleControl.CreateInstance;
var
ClassFactory2: IClassFactory2;
LicKeyStr: WideString;
procedure LicenseCheck(Status: HResult; const Ident: string);
begin
if Status = CLASS_E_NOTLICENSED then
raise EOleError.CreateFmt(Ident, [ClassName]);
OleCheck(Status);
end;
begin
if not (csDesigning in ComponentState) and
(FControlData^.LicenseKey <> nil) then
begin
// ON THE LINE BELOW : the call of CoGetClassObject raise an AV
OleCheck(CoGetClassObject(FControlData^.ClassID, CLSCTX_INPROC_SERVER or
CLSCTX_LOCAL_SERVER, nil, IClassFactory2, ClassFactory2));
LicKeyStr := PWideChar(FControlData^.LicenseKey);
LicenseCheck(ClassFactory2.CreateInstanceLic(nil, nil, IOleObject,
LicKeyStr, FOleObject), SInvalidLicense);
end else
LicenseCheck(CoCreateInstance(FControlData^.ClassID, nil,
CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IOleObject,
FOleObject), SNotLicensed);
end;
As far as I remember there were major enhancements to the ActiveX/TLB import in Delphi 2009 (related to Unicode support) - that might explain it.
In my personal experience Delphi 7 and Delphi 2007 repeatedly failed to import some Windows 7 type libraries (various new interfaces to work with new taskbar), but Delphi 2009 managed that without any problems at all.
As for using Delphi 2009 generated file in earlier versions - beware of Unicode issues. Plus it won't help if the defect is in RTL... Try to make a wrapper ActiveX in Delphi 2009 and use it in Delphi 2007 - that should work.
Sorry to barge in so late after the battle (5 years later as a matter of fact), but I wasted so much time on this precise issue that I thought I should share what I've seen and what I've done to solve it :
2 machines (win7 64 / win 8.1) same delphi 7 (same version same build), same activeX (MapX to name it) with identical .lic files containing the key made of 59 characters :
uQnZi2sFw22L0-MRa8pYX-1E2P8065-5N5M3459-3C934220-04969-6562
same import producing 2 slightly different TLB.
The one working : (on win 8.1) contains this in procedure TMap.InitControlData :
const
CLicenseKey: array[0..61] of Word = ( $0075, $0051, $006E, $005A, $0069, $0032, $0073, $0046, $0077, $0032, $0032
, $004C, $0030, $002D, $004D, $0052, $0061, $0038, $0070, $0059, $0058
, $002D, $0031, $0045, $0032, $0050, $0038, $0030, $0036, $0035, $002D
, $0035, $004E, $0035, $004D, $0033, $0034, $0035, $0039, $002D, $0033
, $0043, $0039, $0033, $0034, $0032, $0032, $0050, $0030, $002D, $004D
, $0030, $0034, $0039, $0036, $0039, $002D, $0036, $0035, $0036, $0032
, $0000);
which translates to a 61 char key
uQnZi2sFw22L0-MRa8pYX-1E2P8065-5N5M3459-3C93422P0-M04969-6562
The TLB that does not work (win 7 64) contains this instead:
const
CLicenseKey: array[0..2] of Word = ( $0050, $004D, $0000);
which translates to a 2 char key
PM
Replacing one const with the other and recompiling the component solved my issue. I don't really know what happened. I just know the Import/TLB produced a bad .pas file that can be corrected manually.

How to recognize the Registered classes in a Delphi Package

I am going through most of my applications and porting them to D2009 and I have one application that makes use of dynamic packages. For the life of me I cannot get my host application to recognize classes registered in a package. I traced through and the initialization section in the package being loaded was called and RegisterClasses was called but when I do a GetClass() call the classes are not available. Is there someone out there who can enlighten me as to what might be going on? I have researched and looked to see if there are any issues with the D2009 release and dynamic packages and so far I have found nothing. I'm beginning to wonder if I have a corrupted installation of Delphi or some other problem.
TIA
If you are using a 3rd party memory manager then make sure it is proven to work with D2009 (actually 2007 and up).
With FastMM (which is the default MM since 2007) you would have to set the UseRuntimePackages define in FastMM4Options.inc
make sure that the following steps are done:
Create a new package in Delphi;
Insert a form in this package;
Insert a "inicialization" section in the form and uses the RegisterClass method. (registerClass(TForm1)); Don't forget the "T".
Save and compile the package;
Close all;
Copy the .bpl file (c:\Users\Public\Documents\RAD Studio\5.0\Bpl) to the application folder;
Create a new aplication in Delphi;
Go in Project > Options > Packages, and check the box "Build with runtime packages";
Leave only "vcl;rtl" in the text field and click OK button;
Insert a button;
In the source of the button, insert the code:
procedure TForm1.Button1Click(Sender: TObject);
var
PackageModule: HModule;
AClass: TPersistentClass;
begin
PackageModule := LoadPackage('Package1.bpl');
if PackageModule <> 0 then
begin
AClass := GetClass('TForm2');
if AClass <> nil then
with TComponentClass(AClass).Create(Application)
as TCustomForm do
begin
ShowModal;
Free;
end;
UnloadPackage(PackageModule);
end;
end;
Compile the application. =)

What is the most common way to create a folder selection dialog using Delphi?

There doesn't appear to be a simple component available to create a folder selection dialog in Delphi 2009, although a file selection dialog is provided by way of the TOpenDialog.
What is the most common way to create a modern folder selection dialog using Delphi?
There are two overloaded routines in FileCtrl.pas called SelectDirectory
For a modern look, use the second form, with sdNewUI
var
dir : string;
begin
dir := 'C:\temp';
FileCtrl.SelectDirectory('Select', 'C:\', dir, [sdNewFolder, sdNewUI], Self);
end;
NOTE: sdNewFolder, sdNewUI etc are only available from D2006+
you can use SelectDirectory from FileCtrl unit
using FileCtrl;
var
St: string;
begin
St:='c:\';
if SelectDirectory(St,[],0) then
begin
end;
end;
You can download a component PBFolderDialog from "http://bak-o-soft.dk/Delphi/PBFolderDialog.aspx" which is quite easy to use and offers access to all options of the Windows "SHBrowseForFolder" dialog; something which the built-in ones not do.
It's freeware with source and not too difficult to port to Delphi 2009.
See the sample code:
Delphi tip#157: select folder dialog
http://www.scalabium.com/faq/dct0157.htm

Resources