Pascal Newsletter #52 - 21-DECEMBER-2004
Contents
1. A Few Words From the Editors
2. How to Add a Program to the Explorer Send To Menu
3. Introductory Principles of Indexed Searching
4. Extracting Records in a Field into a TStringList
5. Returning Classes from a DLL
6. Simplified Collision Detection in Game Programming
7. Forums / Mailing Lists
8. Delphi on the Net
- Components, Libraries and Utilities
- Shareware / Commercial
- Freeware
- Borland Product Updates
- Articles, Tips and Tricks
- Tutorials and Training
- News
- Other / Misc Sites
________________________________________________________________________
1. A Few Words From the Editors
Welcome to the last issue of the Pascal Newsletter for 2004. We'd like
to thank all the authors who contributed articles or prizes this year.
We've got five articles in this issue to give you plenty of reading over
the holiday period and we'd like to thank the authors who contributed
them: Peter Johnson, Jim McKeeth, Stewart Moss, Max Kleiner, John Pears.
We're pleased to award Stewart Moss, Max Kleiner and John Pears the
prizes for this issue:
* Stewart Moss - 'Extracting Records in a Field into a TStringList'
InstallAWARE 3.0 Express Edition - by MimarSinan Int. ($69.95)
InstallAWARE 3.0 for Windows Installer - by MimarSinan International
Develop setups for Windows Installer without any knowledge of MSI!
InstallAWARE automatically converts a conditionally flowing script
into a logo certifiable, ICE-compliant MSI database at build time.
The IDE features a visual UI which generates your setup script for
you automatically and you can fully customize the script behavior.
Special limited offer: 30% off all editions, Enterprise only $559.95!
http://www.installaware.com/landingea.html
* John Pears - 'Simplified Collision Detection in Game Programming'
KnowedgeBASE Vortex 2.9 by Delphinium Software ($49.35)
KnowledgeBASE Vortex features a highly searchable and expandable
information tree viewed in outline or audited within a built-in
wordprocessor. Includes a database for stored references.
http://www.programurl.com/knowledgebase-vortex.htm
* Max Kleiner - 'Returning Classes from a DLL'
KylixDriver v1.1 - by ET Kimberliteware Ltd ($39 / $69 with source)
KylixDriver is a RAD Kylix-oriented and integrated toolkit for PC
hardware access. This toolkit can be efficiently used for writing
Linux device drivers for ISA and PCI hardware.
http://etsoftware.tripod.com/products.html
Special thanks to Delphinium Software for donating KnowledgeBASE Vortex
as an ongoing prize for future issues. In the next issue we have three
prizes up for grabs: InstallAWARE 3.0 Enterprise Edition, KnowedgeBASE
Vortex and YAPI Professional.
* YAPI Professional - by Owen Mooney ($95)
Offers the easiest and yet powerful printing from Delphi. It provides:
WYSIWYG setup, print preview, Non database, Database, text, Grids,
tabs, bitmaps, TCanvas operation, precise positioning or free flow
positioning - all using simple "writeln" statements.
http://www.geocities.com/yapisoftware/
We're also proud to offer readers a special discount on InstallAWARE 3,
thanks to the nice people at at MimarSinan International. InstallAWARE 3
was developed completely in Delphi and helps you author MSI setups with
zero knowledge of Windows Installer. Rather than just providing a visual
UI (like Wise or InstallShield), InstallAWARE has its own RAD scripting
language which is automatically converted to a logo-certifiable MSI
database at build time. Unique features include: Partial Web Deploy;
Genuine Scripting for Windows Installer; Powerful Dialog Editor with
Unique Controls (such as Flash and HTML containers); Advanced 7ZIP
Compression (.NET runtime is 11MB instead of 23MB!). For a limited time,
readers can get 30% off any edition of InstallAWARE 3 by following the
links in this issue.
Next year we're planning to publish seven issues of the newsletter - in
January, March, May, July, September, November and Christmas / New Year.
Now, on with the code...
Regards,
Dave Murray and Ernesto De Spirito
pascal-newsletter-owner@yahoogroups.com
________________________________________________________________________
Help & Manual 3.50 by EC Software - Shareware ($ 299) - Help & Manual is
a WYSIWYG help authoring tool that will aid you in creating standard
WinHelp files (.HLP), Adobe PDF files, HTML pages and the new HTML HELP
(.CHM) files introduced in Windows 98, as well as other file formats and
printed documentation, everything from a single source. This is a must-
have for any software developer. http://www.helpandmanual.com/hmpage.htm
________________________________________________________________________
2. How to Add a Program to the Explorer Send To Menu
By Peter Johnson, Copyright (c) 2003
<delphidabbler at tiscali dot co dot uk>
http://www.delphidabbler.com/
Why Do It
---------
If you are writing a general purpose file-related program it can be
useful to add it to the Windows Explorer "Send To" menu. For example I
place Windows Notepad on the "Send To" menu so I can easily view any
file in the text editor.
How It's Done
-------------
There are two stages achieving our goal:
1. Ensuring our program can receive files sent from the "Send To" menu.
2. Creating an entry for our program in the "Send To" menu.
Although you can create a special handler for the "Send To" menu, we
will take the simple approach of simply storing a shortcut to our
program in the menu.
Receiving Files From the "Send To" Menu
---------------------------------------
This is very simple. If the user selects one or more files, right clicks
and selects Send To | Our program, Windows will simply start our program
and pass the names of the selected files on the command line. So, to
read the files sent from the "Send To" menu, we simply need to check our
command line parameters.
We can do this in our application's FormCreate event handler as follows:
procedure TForm1.FormCreate(Sender: TObject);
var
I: Integer;
begin
for I := 1 to ParamCount do
ProcessFile(ParamStr(I));
end;
Where ProcessFile processes a given file in an application defined way.
(In the demo program that accompanies this article we simply display the
file names in a memo control).
That's all there is to handling the files. Now let's look at how we
create the "Send To" menu entry.
Creating the "Send To" Menu Item
--------------------------------
Windows stores the contents of a user's "Send To" menu in a special
folder. We will need to create a shortcut to our program in that folder.
We must first find the path to the "Send To" folder. Each user has their
own copy of this folder. We find its location by using the
SHGetSpecialFolderLocation and SHGetPathFromIDList API calls (defined in
the ShlObj unit) as follows:
function GetSendToFolder: string;
var
pidl: PItemIDList;
PPath: array[0..MAX_PATH] of AnsiChar;
begin
Result := '';
if SHGetSpecialFolderLocation(0, CSIDL_SENDTO, pidl) = NOERROR then
begin
try
if SHGetPathFromIDList(pidl, PPath) then
Result := PPath;
finally
CoTaskMemFree(pidl);
end;
end;
end;
We first use SHGetSpecialFolderLocation to get a PIDL representing the
required folder. We pass CSIDL_SENDTO to the function to get the PIDL
for the current user's "Send To" folder. If we succeed in getting the
PIDL we then get the path to the folder by passing the PIDL to
SHGetPathFromIDList which stores the required path in a PChar buffer we
supply. We convert the PChar to a string and return this from the
function. Windows allocated memory for the PIDL using its task
allocator. It is our responsibility to free the PIDL, using the
CoTaskMemFree function (defined in the ActiveX unit).
Having found the path to the user's "Send To" folder we can now create a
shortcut to our application in the folder. We may choose to do this in a
set up program or by making this an option in our application. Whatever
our choice, the next section shows how to create a shell link.
Creating a Shell Link
---------------------
The following function can create any shell link -- not only those for
use in the shell link folder.
function CreateShellLink(const LinkFileName, AssocFileName, Desc,
WorkDir, Args, IconFileName: string; const IconIdx: Integer): Boolean;
var
SL: IShellLink; // shell link object
PF: IPersistFile; // persistant file interface to shell link object
begin
// Assume failure
Result := False;
// Ensure COM is initialised
CoInitialize(nil);
try
// Create shell link object
if Succeeded(
CoCreateInstance(
CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, SL
)
) then
begin
// Store required properties of shell link
SL.SetPath(PChar(AssocFileName));
SL.SetDescription(PChar(Desc));
SL.SetWorkingDirectory(PChar(WorkDir));
SL.SetArguments(PChar(Args));
if (IconFileName <> '') and (IconIdx >= 0) then
SL.SetIconLocation(PChar(IconFileName), IconIdx);
// Create persistant file interface to shell link to save link file
PF := SL as IPersistFile;
Result := Succeeded(
PF.Save(PWideChar(WideString(LinkFileName)), True)
);
end;
finally
// Finalize COM
CoUninitialize;
end;
end;
The function has numerous parameters. They are:
const , , , , : string; const : Integer
1. LinkFileName: the full path to the shortcut file -- in our example
we use the name of the "Send To" folder that was returned by
GetSendToFolder, followed by the name of the shortcut file. Note
that the "Send To" menu displays the name of this file, stripped of
it's extension, so give the file a descriptive name.
2. AssocFileName: the name and of the file referenced by the shortcut
-- here we provide the full path to the program to be started from
the "Send To" menu. ParamStr(0) stores this file name.
3. Desc: a description of the shortcut -- this is not displayed in the
"Send To" menu so we pass ''.
4. WorkDir: the program's working directory -- can supply '' if not
required.
5. Args: any command line that is to be passed to the program -- we do
not use this parameter in this example. Remember that the "Send To"
menu also passes file names on the command line.
6. IconFileName: specifies the file containing the shortcut's icon
-- in our example don't specify this file and so the icon is
assumed to be in the program file.
7. IconIdx: the index of the icon in IconFileName or -1 to cause the
program's default icon to be used -- we specify -1.
From the above we can see we need to call CreateShellLink and follows:
...
CreateShellLink(
GetSendToFolder + '\' + 'My SendTo Item.lnk',
ParamStr(0),
'My SendTo Sample Program',
ExtractFileDir(ParamStr(0)),
'',
'',
-1
);
...
Summary
-------
We have now covered the basics of adding an item to the "Send To" menu
and in handling files "sent" to our program from the menu. The code
presented can be used as a basis for implementing "Send To" menu support
in your programs.
A demo application is also included with this issue's source code zip.
It has been tested with Delphi 4 and Delphi 7.
__________________
Peter Johnson is a hobbyist programmer living in West Wales (UK) who
maintains the DelphiDabbler website (http://www.delphidabbler.com/)
where his articles and freeware Delphi applications & components are
published. The code for this article is also available at:
http://www.delphidabbler.com/download.php?file=article-12-demo.zip
________________________________________________________________________
Vote for the Pascal Newsletter in The Borland Top 100!
http://top100borland.com/in.php?who=20
________________________________________________________________________
3. Introductory Principles of Indexed Searching
By Jim McKeeth <jim at mckeeth dot org>
Introduction
------------
There are really two main ways to search a large collection of text
documents. The simplest method would be to load each document and scan
through it for the search terms, this would be referred to as a full
text scan. The second, much faster method is to create an index and then
search the index. An index is a list of terms found in a document or set
of documents. Each word only appears once per document so it is much
shorter then the original document.
Creating An Index
-----------------
Finding The Words
-----------------
In order to create an index you must first parse the document. Parsing,
is the process of picking out the individual tokens (terms or words) in
a piece of text. A parser is a type of state machine. There are many
existing parsing routines available. "The Tomes of Delphi Algorithms and
Data Structures" by Julian Bucknall contains many very good parsers. An
example: http://www.delphi3000.com/articles/article_1265.asp
A simple parser would scan through a string of text, starting at the
beginning, looking at each character. If it is a letter or number then
it is part of a word, if it is white space or punctuation then it is a
separator. Each word is added to a list (i.e. TStringList) in the order
it is found in the document. Typically each word is converted to the
same case (upper or lower).
It is really important to consider what you are indexing and how your
index will be used when creating your index and parsing. For example if
you are parsing HTML then you want to exclude most tags (with the
obvious exception of META tags, which are handled specially). Other
times you might only want to index summery information about each
document.
Indexing The Words
------------------
Now that we have a parsed token list we need to index it. The simplest
index is just a list of each word found in a document, and a reference
to the document. This reference may be a URL, a document name or any
other unique identifier (a GUID or a foreign key to another table
describing the document). A more complex index may include the number of
times the word is found in the document or a ranking for where it is in
the document (in the title, keyword section, first paragraph, middle,
last, etc.) This additional information stored with each word is part of
what differentiates one search engine's performance from another.
Many times certain words are left out. These are called stop words. Stop
words are common words, words that will not be searched on, or words
that will not enhance the meaning of a search. An example of stop words
includes "THE, A, AN, AND, IF, BUT", words with numbers in them, or
anything else you want to filter out. Selecting stop words is another
point of separation of performance.
Some web search engines used to leave out words like "HTML" or "WEB"
because they were so common while other search engines would include
every word. Other search engines start with a dictionary list and only
index words found in that dictionary list. This leads to trouble when
you are indexing names, technical terms or anything else not found in
your original dictionary.
One time I was creating a search engine for a collection newsgroup
articles. I discovered that there was UUEncoded (similar to MIME or
Base64) binaries in the articles. This resulted in my parser finding
words that were hundreds of characters long and total gibberish. I
decided to omit any word longer then 50 characters or shorter then 4.
Making the choices about what to include and what to omit is an
important decision, and will vary based on what content you are
indexing.
So here is an example table structure for your index:
Table: WordList
---------------
Document: Number (foreign key to Documents table)
Word : String[20] (if our longest word is 20 characters)
Count : Number (how many times the word is found)
The primary key would be a compound of Document and Word since each word
is listed once per document.
Table: Documents
----------------
Document : Number(primary key index)
Title : string (title of document)
Location : string (URL or full filename and path)
Optionally you could include the entire document as a blob in this
table. You could also have other tables that lists terms (from the meta
section of the document) or include authors. Again this design choice
depends on the type of documents you are indexing and the purpose of
your search engine.
Searching Your Index
--------------------
Once all the indexes are stored in a database you need to be able to
search the index for a document. A simple SQL statement to search for a
document that contains a single word could look like this:
SELECT *
FROM WordList
WHERE Word = :v_search_term
ORDER BY Count DESC
This returns all documents containing your single search term and they
are ordered by the number of times the word is found. If you want to use
SQL then to search on multiple terms involves an join for each term.
Instead you could retrieve a list for each term and then merge them
manually. This is where you would support AND, OR or NOT key words.
If you want to allow phrase searching then you could search for each
word in the phrase and then search those documents for the phrase. The
same technique could be used for the NEAR key word. There are other more
advanced techniques to do this that are much quicker, but they are
beyond the scope of this document.
Once the hits are found and ranked then display the title of each
document, possibly a summary or the context of the hits, and provide a
way for your user to reach the document.
Variations
----------
One thing Google does a little differently is they look at how pages are
linked. This works really well with the hyper linked nature of the web.
For example if you search for Borland most pages that mention Borland
link to www.borland.com. This is assumed to indicate that
www.borland.com is a very important site about Borland. Google also
limits the number of hits you get on each domain.
Many search engines also rank pages higher if the search term appears in
the URL or title of the page. They also look at the description and
keywords meta tags for ranking. Some search engines will actually ignore
a word if it appears too often in a page. This weeds out sites that try
to artificially inflate their rankings.
Phonetics or Soundex is another technique that can be used. This could
be done with an additional table similar to the word table, but instead
store the soundex value for the words instead of the actual word.
Third Party Search Tools
------------------------
dtSearch http://www.dtsearch.com/
--------
dtSearch provides a full range of text search products. These products
target everyone: from the end user to the media publisher and finally
the developer. Their dtSearch Text Retrieval Engine is the core of all
their products and they provide an API with Delphi examples. This
product is just about creating a full text index of documents and
searching it. They use their own data format. Using their API you can
create a Delphi application to index just about any document (PDF,
Office, ZIP, etc. and Text too!) and then search that index to find the
matching documents.
They recently added support for Linux and .NET but I haven't tested
these with Linux or Delphi for .NET yet.
Depending on what type of project you are working on, one of their other
product lines might be a good match. Their dtSearch Publish, for
example, lets you create a CD / DVD of searchable content quickly and
easily. While their dtSearch Web is idea for building a web search
engine.
Rubicon http://www.fulltextsearch.com/
-------
Tamarack Associates' provides their flagship product Rubicon to Delphi
and C++Builder developers who want indexed searching without building a
system from scratch. Beyond the basics we cover here, they also offer
many advanced features and speed improvements.
If you visit their web site you can download a demo version of their
search tools or test their newsgroup search in Borland and Microsoft's
newsgroups. Not only does Rubicon allow searching of documents (It comes
with a parser to handle text, HTML, and RTF), but it will also allow you
to search your database for data. It supports logical expression (and,
or, not, near and like), as well as support for full phrases. It is all
pure Delphi source, and really offers the developer a very high level of
control over the process.
Rubicon's FastPhrase technology builds a much larger table that allows
it to perform phrase searches without performing a full text scan of the
target document. This is done by not only storing each word, but also
storing a concatenation of each word and it's two adjacent words, for a
total of up to there entries per word.
Rubicon boasts very comprehensive database compatibility. Supported
databases include the BDE and dbExpress as well as ADO, Advantage,
Apollo, Direct Oracle Access, DBISAM, FlashFiler, Halcyon, Interbase
Express, Interbase Objects, ODBC Express and Topaz. Other databases are
supported through building your own packages. When installing Rubicon
(either demo or full version) be sure to follow the directions to
install it correctly and so it will support your selected database.
Summary
-------
Based on my comparisons between dtSearch and Rubicon, they both perform
about the same in the search speed department. dtSearch's advantage is
in their additional product lines and simpler interface, but you suffer
from less configurability. Rubicon gives you access to every detail of
your search project by providing you with the complete Delphi source and
your choice of databases instead of dtSearch's closed database and DLL.
Database Search Features
------------------------
Many databases provide features to allow you to index and search
documents stored within the database. Oracle offers an additional add-in
to index documents. MySQL by default allows you to search stored text
documents just like you would any other field. DBISAM (a native Delphi
BDE replacement with no deployment) now has text indexing and searching
as well.
Conclusion
----------
Searching a shorter and well organized index is much quicker then
searching an entire document. Creating and searching an index takes a
lot more planning and effort up front, but quickly pays off if the text
is searched very often. Typically the larger and more complex the index,
the more effective the search. If your index gets too large or complex
then the search speed will degrade.
There are off the shelf searching tools available to end users and
developers alike. dtSearch and Rubicon are both extremely fast and
useful, but don't let that stop you from designing your own, especially
if you have a specialized need.
See also: http://www.dtsearch.com/dtsoftware.html#Art_of_The_Text_Query
________________________________________________________________________
InstallAWARE 3.0 for Windows Installer by MimarSinan International
Special time limited offer: 30% off Enterprise Edition, only $559.95!
InstallAWARE is a next generation setup authoring tool with unique
features such as partial web deployment, Flash and HTML progress
billboards, ten striking setup themes, fully customizable installation
dialogs, and a setup script that automatically gets converted to a
Windows Installer file. >> http://www.installaware.com/landingea.html <<
________________________________________________________________________
4. Extracting Records in a Field into a TStringList
By Stewart Moss <stewart at new-heights.co.za>
http://www.new-heights.co.za/
Introduction
------------
Often the programmer needs a quick and dirty method to extract a set of
records from a specific field in a dataset in a convenient way.
Examples of this in my own programming are when I needed to populate a
TListBox or TComboBox (on a modal form) with values that the user can
select for reporting or other purposes.
This simple class is a safe and convenient way to do this. The current
record in the dataset is restored, and the dataset's active state (ie
open or closed).
A demo application is also included with this issue's source code zip.
Implementation
--------------
The code simply gets a TField object from a specified field name
(property called "FieldName") belonging to the dataset (property called
"Dataset") and iterates through the records returning each value in the
field, from start to finish.
The TField class is handy because it allows us to handle any field type
based on any dataset :)
Only datatypes which support the .AsString method (ie not blobs) are
returned.
A boolean property of the class (called "emptyNulls") will allow you to
return blank rows if found. This is useful if you need to return the
"offset" in the dataset of the required record (ie matching
DataSet.RecNo) or if blank rows are meaningful.
The output is in a read only property called Strings of type
TStringList. This property can be used to directly populate a TListBox
or even Strings.SaveToFile(). The output is based on system formatting
variables (for dates etc) so beware!
The Refresh method is fired then the Strings property is read and the
list needs to be refreshed. This happens when you change the dataset or
the fieldname for the first time, you can also call this manually.
The output can be padded with leading and trailing and leading strings.
This is useful if you need to pad the text for formatting. However this
padding needs to be removed from the return of the TListBox or TComboBox
(for use in lookup queries etc). Honestly I don't use this this padding
feature in my own code.
The class has a method called "quickSearch", this allows you to perform
a lookup based on any return value. This is just a wrapper of the
TDataset.Locate() on the current dataset. For example you could present
all CustomerNames in a drop down list, and quickSearch() will allow you
to locate the CustomerID of the selected CustomerName. The lookup is
returned as a String.
Example of Usage
----------------
This populates the TListBox called SrcList on TfrmSelectData with the
names of the active stock as returned from the TQuery named
qryPortfolio. Then performs a lookup to determine the StockID of the
stock name.
procedure TFormMain.thingy;
var
StockID, StockName : string;
DatasetExtract : TDatasetExtract;
begin
DatasetExtract := TDatasetExtract.Create;
try
// any field
DatasetExtract.FieldName := 'StockName';
// any dataset
DatasetExtract.DataSet := qryPortFolio;
// create the form
with TfrmSelectData.Create(Self) do
begin
// add a copy of the DatabaseExtract TStringlist to the TListBox
// Getting the strings could generate an exception.
SrcList.Items.AddStrings(DatasetExtract.Strings);
// show the form
ShowModal;
// if he pressed ok
if ModalResult = mrOK then
begin
// Return the stock name from the selected index in the list
StockName := SrcList.Items[SrcList.selectedindex];
// Lookup the StockID from qryPortfolio query using the class
StockID := DatasetExtract.Search('StockName', StockName,
'StockID',[]);
showmessage('The StockID of '+StockName+' is '+StockID);
end;
free;
end; // with
finally
DatasetExtract.free;
end;
end;
Class Code
----------
{-----------------------------------------------------------------------
Unit Name: unitDatasetExtract2
Modification Date: 18 December 2004
Creation Date: 04 June 02 00:39:21
Documentation Date: 04 June 02 00:39:21
Release Date: 15 Jan 2003
Version: 2.0
Author: Stewart Moss
Compiler version:
Delphi 5 and Delphi 6 tested
Purpose:
To Extract a specific field from a dataset in a TStringList. Useful
for populating TListBoxes that you dont want to be data aware...
(Released originally on Delphi3000.com)
Description:
At the moment it only support TStringLists. It will convert
most TField.FieldType into a string
Notes:
Dependancies:
History:
15 Jan 2003: Posted at wwww.delphi3000.com. Article number 3512.
1122 visits by Dec 2004
Copyright 2002, 2003, 2004 by Stewart Moss
All rights reserved.
You must not modify this Unit Header.
-----------------------------------------------------------------------}
unit unitDatasetExtract2;
interface
uses Classes, db{$IFDEF VER140}, Variants{$ENDIF};
type
TDatasetExtract = class
private
fEmptyNulls: boolean;
recPos: integer;
fFieldname,
fappend,
fprepend: string;
fDataset: TDataset;
fStrings: TStringList;
refreshed: boolean;
function FieldToString(Field: TField): string;
function Get_Strings: TStringList;
procedure Set_Dataset(const Value: TDataset);
procedure Set_Fieldname(const Value: string);
public
constructor create;
destructor destroy; override;
procedure Refresh;
function Search(searchField, searchValue, ReturnField: string;
Locateoptions: TLocateOptions): string;
published
// You have the option of appending and prepending any information
// to the begining of each record.
// Useful for creating delimited records easily (ie you can just add
// the StringList items together) (maybe not really that useful :P )
property append: string read fappend write fappend;
property prepend: string read fprepend write fprepend;
// Whether or not nulls must be translated into blank values,
// or ignored
property EmptyNulls: boolean read fEmptyNulls write fEmptyNulls
default true;
// The field name to return in the string list
property FieldName: string read fFieldname write Set_Fieldname;
// The dataset of the field
property Dataset: TDataset read fDataset write Set_Dataset;
// This is the TStringList output of the class. Reading this string
// triggers the action of the class.
property Strings: TStringList read Get_Strings;
end;
implementation
uses Sysutils; // allow exception objects
{ TDatasetExtract }
constructor TDatasetExtract.create;
begin
fDataset := nil;
fStrings := TStringList.create;
EmptyNulls := true; // allow null rows by default
refreshed := false; // we do not have data
end;
destructor TDatasetExtract.destroy;
begin
fStrings.free;
inherited;
end;
procedure TDatasetExtract.Refresh;
{-----------------------------------------------------------------------
Procedure: TDatasetExtract.Refresh
Starts at the beginning of the record set and appends the required
field in each consecutive record to the string list using the TField.
----------------------------------------------------------------------}
var
Field : TField;
isactive : boolean;
begin
with fDataset do
begin
try
// turn off any data-aware components related to current dataset
disablecontrols;
// save Dataset open state
isactive := fDataset.Active;
if not isactive then
fDataset.open;
// Save our current place in the dataset
recPos := RecNo;
// go to the start
First;
while not eof do
begin
// Get the TField object for field FieldName at
// the current position (we don't care what type)
Field := FieldByName(fFieldname);
// Ok is it null?
if not varisnull(Field.asvariant) then
// use our "safer" .AsString
fStrings.add(fprepend + FieldToString(Field) + fappend)
else if EmptyNulls then
// we are allowed to insert nulls
fStrings.add(fprepend + fappend);
next;
end; // while not eof
finally
// Restore our current place in the dataset
RecNo := recPos;
// if the dataset was closed then close it
if not isactive then
fDataset.close;
// turn on the data-aware components related to current dataset
enablecontrols;
end; // finally
end; // with fDataset
end;
function TDatasetExtract.FieldToString(Field: TField): string;
{-----------------------------------------------------------------------
Procedure: TDatasetExtract.FieldToString
Arguments: Field: TField
Result: string
This actually reads the field from the database and swallows any
EDatabaseErrors.
----------------------------------------------------------------------}
begin
try
result := Field.AsString;
except
on e: EDatabaseError do
begin
// nothing
end
else
// re-raise the exception if it is something else
raise;
end;
end;
function TDatasetExtract.Get_Strings: TStringList;
begin
result := fStrings; // always return what you have (even if exception)
if refreshed then // if we have clean data
exit; // then we are done
fStrings.clear;
if (fDataset = nil) or (fFieldname = '') then
// uber cool error message
raise exception.create(self.ClassName +
': Two manditory fields not supplied');
Refresh;
end;
function TDatasetExtract.Search(searchField, searchValue,
ReturnField: string; Locateoptions: TLocateOptions): string;
{-----------------------------------------------------------------------
Procedure: TDatasetExtract.quickSearch
Arguments: searchField, searchValue, ReturnField : string;
Locateoptions: TLocateOptions
Result: string
Searches for a field value in a specified field name and returns the
specified field returns '' is nothing is found.
eg
Ask for a customer id of 10 and return the customer name
----------------------------------------------------------------------}
var
isactive : boolean;
begin
with fDataset do
begin
// turn off any data-aware components related to the current dataset
disablecontrols;
// save Dataset open state
isactive := fDataset.Active;
if not isactive then
fDataset.open;
try
result := '';
First;
if not locate(searchField, searchValue, Locateoptions) then
exit;
// use our "safer" .AsString method
result := FieldToString(FieldByName(ReturnField));
finally
// our current place obeys TDataset.Locate()
// if the dataset was closed then close it
if not isactive then
fDataset.close;
// turn on any data-aware components related to the current dataset
enablecontrols;
end;
end;
end;
procedure TDatasetExtract.Set_Dataset(const Value: TDataset);
begin
fDataset := Value;
refreshed := false; // we are dirty again
end;
procedure TDatasetExtract.Set_Fieldname(const Value: string);
begin
fFieldname := Value;
refreshed := false; // we are dirty again
end;
end.
________________________________________________________________________
Vote for the Pascal Newsletter in The Delphi Top 200!
http://top200.jazarsoft.com/delphi/rank.php3?id=latium
________________________________________________________________________
5. Returning Classes from a DLL
By Max Kleiner <max@kleiner.com>
Kleiner Kommunikation Reference: http://max.kleiner.com/
Component Download: http://max.kleiner.com/download/dllplus.zip
Question/Problem/Abstract:
--------------------------
Export an object-reference from a DLL is one approach to get real
OO-access to a DLL. The DLL must create and return the object, so the
client gets the methods without encapsulating. Let's see how this
framework, called DLL+, works...
Answer:
-------
There is also an example uploaded with UML-Diagrams (*.tif) from
ModelMaker. We always work with MM since we had to redesign a big
project.
First, we have to built an abstract class in a separate unit (see below
the same with a real interface). You might consider this unit like an
interface:
unit income1;
interface
type
IIncome = class
public
function GetIncome(const aNetto: Currency): Currency;
virtual; abstract;
procedure SetRate(const aPercent, aYear: integer);
virtual; abstract;
function queryDLLInterface(var queryList: TStringList):
TStringList; virtual; abstract;
end;
Second we built the DLL in a new unit (*.dpr) with the corresponding
class, which has to implement the methods from the interface:
type
TIncomeReal = class(IIncome)
private
FRate: Real;
public
constructor Create;
function GetIncome(const aNetto: Currency): Currency; override;
procedure SetRate(const aPercent, aYear: integer); override;
...
And now comes the export, cause objects in DLL+ are created by calling a
global Constructor function, you can see that returning objects from the
function that creates them is acceptable by the client:
{-------------------------------------------------------------}
function CreateIncome: TIncomeReal; stdcall;
begin result:= TIncomeReal.Create; end;
exports CreateIncome resident;
begin {fake} end.
{-------------------------------------------------------------}
At last we take a look at the client. In managing objects the client
consider who owns the object and is responsible for freeing it up:
Uses income1;
private
IncomeRef: IIncome; // member
...
function CreateIncome:IIncome; stdcall; external('income.dll');
...
procedure TfrmIncome.FormCreate(Sender: TObject);
begin
IncomeRef:=createIncome;
end;
So the access is easy, stable and improves maintenance of the DLL. It
should be mandatory to implement a function called queryDLLInterface, in
order to reproduce the interface and all the parameters in case of lost
(see example).
procedure TfrmIncome.BitBtnOKClick(Sender: TObject);
begin
incomeRef.SetRate(strToInt(edtZins.text), strToInt(edtJahre.text));
cIncome:= incomeRef.GetIncome(StrToFloat(edtBetrag.Text));
edtBetrag.text:= Format('%m',[cIncome]);
end;
Calling an Interface
--------------------
Now the client calls an InterfaceReference:
private
incomeIntRef: IIncomeInt;
procedure TfrmIncome.BitBtnOKClick(Sender: TObject);
begin
incomeIntRef:=createIncome;
try
with incomeIntRef do begin
if QueryInterface(IIncomeInt, incomeIntRef) = S_OK then begin
SetRate(strToInt(edtZins.text), strToInt(edtJahre.text));
cIncome:=strTofloat(edtBetrag.text);
The Unit Income1 is enlarged with the interface:
IIncomeInt = interface (IUnknown)
['{DBB42A04-E60F-41EC-870A-314D68B6913C}']
function GetIncome(const aNetto: Currency): Currency; stdcall;
function GetRate: Real;
function queryDLLInterface(var queryList: TStringList):
TStringList; stdcall;
procedure SetRate(const aPercent, aYear: integer); stdcall;
property Rate: Real read GetRate;
end;
The DLL now exports a real Interface-Pointer:
TIncomeRealIntf = class (TInterfacedObject, IIncomeInt)
private
FRate: Real;
function Power(X: Real; Y: Integer): Real;
protected
function GetRate: Real;
public
constructor Create;
destructor destroy; override;
function GetIncome(const aNetto: Currency): Currency; stdcall;
function queryDLLInterface(var queryList: TStringList):
TStringList; stdcall;
procedure SetRate(const aPercent, aYear: integer); stdcall;
property Rate: Real read GetRate;
end;
function CreateIncome: IIncomeInt; stdcall;
begin
result:= TIncomeRealIntf.Create;
end;
When n-classes implements one interface push a parameter to the export
routine in the DLL:
function CreateIncome(intfID: byte): IIncomeInt; stdcall;
begin
case intfID of
1: result:= TIncomeRealIntf.Create;
2: result:= TIncomeRealSuper.Create;
3: result:= TIncomeRealSuper2.Create;
end;
end;
exports CreateIncome;
Client-calling looks like this:
incomeIntRef := createIncome(3);
________________________________________________________________________
KnowedgeBASE Vortex 2.9 by Delphinium Software ($49.35 US)
KnowledgeBASE Vortex features a highly searchable and expandable
information tree viewed in outline or audited within a built-in
wordprocessor. Includes a database for stored references.
http://www.programurl.com/knowledgebase-vortex.htm
________________________________________________________________________
6. Simplified Collision Detection in Game Programming
By John Pears <j.pears@coventry.ac.uk>
The, so called, 'simple collision detection algorithms' only detect
collisions between two rectangles yet the most simple of them seem to be
over complicated. Each sprite has x and y coordinates (usually the
centre of the sprite) and a rectangle used for placing the image.
Sometimes, a separate 'bounding rectangle' is used for collision
detection.
Each time the sprite's x,y is moved, the positions of the rectangle(s)
have to recalculated. The collision detection then tests left, top,
right and bottom of BOTH sprites rectangles to see if a collision
occurred. All of this has to be done for each sprite on each step of the
game.
How about only moving the x,y (centre) of the sprite and "fixing" the
offsets to the left and top?
Consider the following data structure:
type
TSpriteRec = record
Centre : tpoint;
OffSet : tpoint; // never changes unless change of image.picture
Image : TImage;
end;
var
Invader : array[1..A_NUMBER] of tSpriteRec;
Rocket : array[1..ANOTHER_NUMBER] of tSpriteRec;
Placing the sprite becomes:
Image.Left = ( Centre.x - OffSet.x );
Image.Top = ( Centre.y - OffSet.y );
No more code, its there, job done, the offsets never change.
We can now write a simple function to detect collision:
Function Collided(Spr1, Spr2 : TSpriteRec) : Boolean;
begin
result :=
(abs(Spr1.Centre.x-Spr2.Centre.x) < (Spr1.OffSet.x+Spr2.OffSet.x)) and
(abs(Spr1.Centre.y-Spr2.Centre.y) < (Spr1.OffSet.y+Spr2.OffSet.y));
end;
And, our main code becomes:
if Collided (Rocket[10], Invader[77]) then begin
// some code
end;
The demo application included in this issue's source code zip is a
simple 'Space Invaders' type game. It was written with Delphi 6 and has
no DirectX or DelphiX. It is just raw Delphi moving TImages around.
The code is not identical to the above examples but the principle is.
In the demo try changing the following constants in U_Sprites.pas:
INVADER_COLS = 16;
INVADER_ROWS = 6;
________________________________________________________________________
Vote for the Pascal Newsletter in The Programming Pages!
http://www.programmingpages.com/?r=latiumsoftwarecomenpascal
________________________________________________________________________
7. Forums / Mailing Lists
To join any of our forums, the best way is to subscribe from the web,
since then you'll be able to access the website features (message
archive, files section, etc). A Yahoo! ID is required for that, and you
can get yours free by registering as a Yahoo! user, but you can also
subscribe by email (you'll only have email access).
* Delphi-En: A unique forum for intermediate-level Delphi programmers.
A large group with a helpful community of members. If you are a beginner
please stay as a listener and learn from others' questions and answers.
Home Page: http://groups.yahoo.com/group/delphi-en/
Subscription: http://groups.yahoo.com/group/delphi-en/join
delphi-en-subscribe@yahoogroups.com
* Delphi-All: A Delphi group open to programmers of all levels.
Home Page: http://groups.yahoo.com/group/delphi-all/
Subscription: http://groups.yahoo.com/group/delphi-all/join
delphi-all-subscribe@yahoogroups.com
* Kylix: Kylix programming.
Home Page: http://groups.yahoo.com/group/KylixGroup/
Subscription: http://groups.yahoo.com/group/KylixGroup/join
KylixGroup-subscribe@yahoogroups.com
* Components: This is a forum for searching / recommending software
components (VCL and CLX components, ActiveX objects, DLL libraries,
.Net, etc.), as well as utilities, tutorials, information, etc.
Home Page: http://tech.groups.yahoo.com/group/components/
Subscription: http://tech.groups.yahoo.com/group/components/join
components-subscribe@yahoogroups.com
* Software Developers: A place for subjects related to software
development and the industry. For developers to share their experiences
as an academic, professional or hobbyist. It is not a programming forum,
messages here are supposed to be more general or language independent.
Home Page: http://tech.groups.yahoo.com/group/software-developers/
Subscription: http://tech.groups.yahoo.com/group/software-developers/join
software-developers-subscribe@yahoogroups.com
________________________________________________________________________
Delphi-PRAXiS · One of the fastest growing German Delphi-forums, with
unique services like our "Delphi-PRAXiS Expert" (add-on which allows
access to our libraries directly from within the IDE). Our database
contains more than 50,000 articles. >>> http://www.delphipraxis.net <<<
________________________________________________________________________
8. Delphi on the Net
By Dave Murray <irongut at vodafone dot net>
Components, Libraries and Utilities
===================================
Shareware / Commercial
----------------------
* InstallAWARE 3.0 for Windows Installer - by MimarSinan International
Develop setups for Windows Installer without any knowledge of MSI!
InstallAWARE automatically converts a conditionally flowing script
into a logo certifiable, ICE-compliant MSI database at build time.
The IDE features a visual UI which generates your setup script for
you automatically and you can fully customize the script behavior.
Special limited offer: 30% off all editions, Enterprise only $559.95!
http://www.installaware.com/landingea.html
* KnowedgeBASE Vortex 2.9 by Delphinium Software ($49.35)
KnowledgeBASE Vortex features a highly searchable and expandable
information tree viewed in outline or audited within a built-in
wordprocessor. Includes a database for stored references.
http://www.programurl.com/knowledgebase-vortex.htm
* YAPI Professional - by Owen Mooney ($95)
Offers the easiest and yet powerful printing from Delphi. It provides:
WYSIWYG setup, print preview, Non database, Database, text, Grids,
tabs, bitmaps, TCanvas operation, precise positioning or free flow
positioning - all using simple "writeln" statements.
http://www.geocities.com/yapisoftware/
Freeware
--------
* CSV Parser v1.0 - by Patrick Beekmans (with source)
Parse any CSV-file with this component. You have the ability to choose
the desired separator. This component has three events:
OnNewColumnHeader, OnNewRow and OnNewValue.
http://www.torry.net/vcl/vcltools/text/PBParsers.zip
* GExperts v1.21 - by GExperts Inc. (with source)
GExperts is a set of open source tools that increase productivity by
adding features to the IDE. Includes: Editor Experts to find matching
delimiters, insert unit headers, etc; IDE enhancements that add a
Windows menu and show hidden menu items; Palette enhancements that add
multi-line tabs or add tabs to the context menu; and much more. Now
supports Delphi 5/6/7/8/2005 and C++Builder 6.
http://www.gexperts.org/
* Indy v10.0.51 - by The Indy Pit Crew (with source)
Open source suite of more than 120 protocols and Internet standards.
Each protocol is robust with rich support, the need to add additional
support to existing protocols is rare. Indy is easy to use because it
uses blocking sockets; everything happens in a sequence, just like
accessing a file. Now supports .Net.
http://www.indyproject.org/
* PGP Components for Delphi v4.0.1 - Michael in der Wiesche (w. source)
Provides a Delphi (2-7) direct interface to PGP 6.5.x, 7.x or 8.x. New
in Version 4.0.1: Checking and restarting of the PGPsdkService have
been fixed, modified and enhanced; Error handling in TPGPDecode's data
analysis has been slightly adjusted for special cases.
http://idw-doc.homepage.t-online.de/PGPcomp.htm
* ProDelphi v17.3 - by Helmuth J. H. Adolph
Source code profiler for Delphi (runtime measurement). Features
include: Cyclic storage of measurement results for long period
measurement; Open the source in the Delphi editor by clicking a
procedure in the viewer; Conditional compilation; Integrated into the
Delphi IDE; Measures runtimes in DLL's; Delphi 2005 Win32 supported.
http://www.prodelphi.de/
* ProDelphi.Net v3.0 - by Helmuth J. H. Adolph
Source code profiler for Delphi 8 and Delphi 2005. It has the same
features as ProDelphi except measuring functions written with the
inline assembler (not supported for .Net platform).
http://www.prodelphi.de/
* TscFontCombobox v1.1 - by Stefan Cruysberghs (with source)
An advanced combobox which shows the available Windows fonts. A lot of
features for preview, used fonts, show font types (truetype, printer,
symbol), etc are provided. This component provides all features of the
Microsoft and Corel font combobox.
www.torry.net/news.php?id=26&SID=d05e863b8b4107c854fa651e2bbfdeaa
* Vector Graphics ActiveX v1.6.0 - by Stas Semenov
A graphics component for creating technical drawings, illustrations
and presentation, training material and business reports, charts and
diagrams and more. Based on Layer-Class-Shape architecture that
repeatedly reduces the size of the stored data, to increase speed of
loading and displaying documents, and also to provide excellent speed of
execution with documents containing around 1,000,000 shapes.
http://www.script-debugger.com/
* XP Graph v2.1 - by JLx Soft
A Delphi Chart component equal like that one in Windows' task manager
with bar and history, plus additional extensions.
http://comps.jlxsoft.com/
Borland Product Updates
-----------------------
* Delphi 2005: The Ultimate Delphi
The complete development solution for Windows. With all of the Windows
languages and SDKs you need in one environment for modern Windows
rapid application development (RAD), Delphi 2005 takes the power of
Delphi to the next level. With Delphi, C#, Microsoft .NET Framework
and Win32 support for GUI, Web, database, modeling, and ALM in one
hyperproductive RAD environment, Delphi 2005 makes Windows development
tasks faster, better, and easier.
http://www.borland.com/delphi/
Articles, Tips and Tricks
=========================
* BDNradio: Delphi 2005 Live Chat on Interop with Chris Bensen
In this audio replay, Chris discusses his work on ActiveX, COM, .NET
interop, VLI and the New Component wizard.
http://community.borland.com/article/0,1410,32858,00.html
* BDNRadio: Log from Chat with Corbin Dunn on Delphi 2005 IDE Features
Read the chat room log for questions answered by Corbin on Delphi 2005
IDE features, and listen to the replay.
http://community.borland.com/article/0,1410,32850,00.html
* BDNRadio: Delphi 2005 IDE Chat with Allen Bauer
This is a log for the live audio chat from November 24th 2004 on
Delphi 2005 with Allen Bauer, a Borland Principal Engineer, and
Delphi IDE architect. Allen discusses his work on Delphi 2005.
http://community.borland.com/article/0,1410,32843,00.html
* Delphi 2005 Fixes for QualityCentral Bug Reports
There are currently 263 QualityCentral bug reports closed with the
release of Delphi 2005.
http://community.borland.com/article/0,1410,32837,00.html
* Namespaces in Delphi 2005
To make Delphi code friendlier towards other .NET languages Borland
has changed the way Delphi 2005 produces namespaces. This article
discusses the changes that have been made and how they affect you.
http://community.borland.com/article/0,1410,32765,00.html
* Advanced Markup Language Generation for IntraWeb
Describes how to use an undocumented feature in IntraWeb to create
complex controls that require multiple tags.
http://community.borland.com/article/0,1410,32758,00.html
* BDNradio: Chat Room Log of Live Chat with Danny Thorpe on Delphi 2005
This is the chat log for the live audio chat from November 19th 2004
on Delphi 2005 with Danny Thorpe, a Borland Chief Scientist and
architect of the Delphi compilers. Danny discusses changes and
enhancements to the Delphi Win32 and Microsoft.NET compilers, the run
time framework and .NET support in general.
http://community.borland.com/article/0,1410,32789,00.html
* Using XMLDoc For API Documentation And HelpInsight With Delphi 2005
How to use Borland's XMLDoc tool to quickly and easily document your
software and generate HelpInsight for your components.
http://community.borland.com/article/0,1410,32770,00.html
* What's New in Delphi 2005 - by Bob Swart
A Technical White Paper on all that's new in Delphi 2005.
http://community.borland.com/article/0,1410,32778,00.html
* Building a custom data provider for .Text
A case study on the porting of .Text from SQL Server to InterBase
using Delphi for .NET.
http://community.borland.com/article/0,1410,32419,00.html
* Borland Conference 2004 Blogs
An impressive compilation of blog entries that were created during
BorCon 2004. It's not as good as being there, but it's close.
http://community.borland.com/article/0,1410,32752,00.html
* How to Check if a Document in a TWebBrowser is Located on a Local
(or Network) Drive - by Zarko Gajic
If you need to know the location of a document displayed in a
TWebBrowser component, you need to get the Protocol property of the
IHTMLLocation. Here's a function that returns true if a document in a
WebBrowser is stored locally.
http://delphi.about.com/od/adptips2004/a/bltip1204_5.htm
* Using the TDBGrid Component - by Zarko Gajic
Contrary to most other Delphi data-aware controls the DBGrid component
has many nice features and is more powerful than you would have
thought. There are many ways to customise the output of a DBGrid...
http://delphi.about.com/od/usedbvcl/a/tdbgrid.htm
* Retrieving All Image Links from an HTML Document - by mrbaseball34
Here's how to obtain all image links from an HTML document using Indy.
http://delphi.about.com/od/adptips2004/a/bltip1204_3.htm
* Making Delphi 2005 Independent from .NET - by Alvaro Garcia Pascual
Despite what Borland says, Delphi 2005 doesn't require .NET. If you
are a Delphi Win32 developer and don't like that Delphi 2005 comes
polluted with .NET stuff, read this article to learn how to remove
.Net from Delphi 2005.
http://delphi.about.com/od/delphifornet/a/delphi2005win32.htm
* A First Look at Delphi 2005 - by Zarko Gajic
The time has come to take a sneak peak into a new Delphi version:
Delphi 2005. Delphi 2005 is the ultimate weapon for developers:
Delphi, C#, Win32 and .NET in one RAD environment.
http://delphi.about.com/od/productreviews/ss/delphi2005first.htm
* How to write a Ping utility using ICMP.dll - by Serge Perevoznyk
Raw Sockets are subject to security checks and are accessible only to
members of the administrator's group. Icmp.dll provides functionality
that allows developers to write Internet ping applications on Windows
systems without Winsock 2 support and without security problems.
http://www.delphi-central.com/tutorials/icmp-ping.aspx
* How To Find an Item in a Tree Control Via its Label - Serge Perevoznyk
The "tree view" control does not have a built-in method for searching
the entire tree or for selecting an item given its label. This article
provides code that returns the location of any item in a tree when
given a specific label to search for.
http://www.delphi-central.com/tutorials/FindTreeViewNode.aspx
Tutorials and Training
======================
* Installable Delphi 2005 Examples
Download an installation for dozens of tested Delphi 2005 examples for
use directly from the IDE. These examples include the C# and Delphi
languages and both the Win32 and .NET platforms with text that
introduces and explains them.
http://community.borland.com/article/0,1410,32857,00.html
* BDNtv: C++Builder in Delphi
In this quick preview, Troy Kitch shows integration of C++Builder
features in Delphi 2005. Flash
http://bdntv.borland.com/cppbuilder/CPPinDelphi8x6.html
* BDNtv: Unit testing in Delphi 2005
This BDNtv episode shows the unit testing integration for DUnit for a
Delphi/Win32 application in Delphi 2005. Unit testing for C#, Delphi
for .NET, and Delphi for Win32 with both NUnit and DUnit are supported
in Delphi 2005. Flash
http://dotnet.borland.com/bdntv/delphi/d2005unittesting8x6.html
* GOF Behavioural Patterns with C#: Part 1 - by Barry Mossman
This is the third article in a series upon the GOF Design patterns
from a C# and .Net Framework perspective. It is covers some of the
Behavioral Patterns: Chain of Responsibility, Command, Interpreter.
http://community.borland.com/article/0,1410,32710,00.html
* GOF Behavioural Patterns with C#: Part 2 - by Barry Mossman
This is the fourth article in a series upon the GOF Design patterns
from a C# and .Net Framework perspective. It is a continuation of the
Behavioral Patterns this time looking at Iterator, Mediator, Observer
and Memento (Momento) patterns.
http://community.borland.com/article/0,1410,32795,00.html
* Deriving a Model From an Existing Database with ECO II in Delphi 2005
Henrik Jondell demonstrates how easy it is to create model-powered
applications for your existing databases with ECO II. Flash
http://dotnet.borland.com/bdntv/delphi/eco2modelderivation.html
* An Introduction to COM Programming with Delphi (1/6) - by Curtis Socha
A brief historical rundown on COM's glorious past. Abstract methods
vs. Interfaces. Classes and Interfaces: An interesting paradox.
http://delphi.about.com/library/weekly/aa112304a.htm
* An Introduction to COM Programming with Delphi (2/6) - by Curtis Socha
What is an Interface? How to implement an Interface? Describing the
TInterfacedObject.
http://delphi.about.com/library/weekly/aa113004a.htm
* An Introduction to COM Programming with Delphi (3/6) - by Curtis Socha
What is the implements directive? What is the Method Resolution
Clauses? Pseudo-Multiple Interface Inheritance. Interface properties
and other fine tales of horror.
http://delphi.about.com/library/weekly/aa120704a.htm
* An Introduction to COM Programming with Delphi (4/6) - by Curtis Socha
A Com Object walk-a-bout. A Class Factory tour. Our first true COM
Object program. Homework Assignment.
http://delphi.about.com/library/weekly/aa121404a.htm
* An Introduction to COM Programming with Delphi (5/6) - by Curtis Socha
Marshaling Data. Oh, the glory of leadership! Variant Reference Page.
Using Variants and Variant Arrays.
http://delphi.about.com/library/weekly/aa122104a.htm
* Programming a Memory Game in Delphi: Part 1 - by Delphi Central
In this tutorial, we will see how the TDrawGrid component can be used
to help us develop a "Memory" game. Firstly we will describe what is
involved with the Memory game.
http://www.delphi-central.com/tutorials/memory_game.aspx
* Programming a Memory Game in Delphi: Part 2 - by Delphi Central
In part 1 we explained how to create the form and drawgrid at design
time. Now we will move onto writing the actual code.
http://www.delphi-central.com/tutorials/memory_game_2.aspx
* Programming a Memory Game in Delphi: Part 3 - by Delphi Central
In part 1 we explained how to create the form and drawgrid at design
time, in part 2 we started writing the actual code. In the third part
of the tutorial we will draw the grid that the game is played on.
http://www.delphi-central.com/tutorials/memory_game_3.aspx
News
====
* Delphi 2005 Architect Review
Delphi has grown up since it launched nearly ten years ago. The latest
version provides support for developing Win32 and .NET applications as
well as supporting the C# language. There are many enhancements to
almost all areas with the main goal of increasing developer
productivity.
http://www.builderau.com.au/program/0,39024614,39170720,00.htm
* Global 2000 Companies Select Borland to Elevate Software Quality
An unprecedented number of high-profile customers spanning a wide
spectrum of industries and regions selected CaliberRM and StarTeam in
2004 as their preferred requirements management and software
configuration and change management solutions. Companies that selected
CaliberRM or StarTeam this year include: British Telecom, Comcast,
EDS, Gap, HP, Jaguar Cars, Siemens AG, Symantec and Verizon Wireless.
http://home.businesswire.com/portal/site/google/index.jsp?
ndmViewId=news_view&newsId=20041206005289
* BDNradio Interviews with Borland's R&D staff for Delphi 2005
Don't miss these live interviews with Borland R&D engineers.
http://community.borland.com/article/0,1410,32786,00.html
* Software Delivery Optimisation Enables Disciplined Approach
At the Borland Conference 2004, Dale Fuller, President and CEO,
presented their vision and product strategy for transforming software
development from an unpredictable art form into a more manageable and
repeatable business process.
http://www.itweb.co.za/sections/business/2004/0411150801.asp
* Borland's ALM Products Receive Numerous Accolades in 2004
Borland today announced 2004 as a banner year for its products, with
receiving numerous industry accolades and awards from around the
globe. Industry recognition of their innovative solutions provides the
company with significant momentum leading into 2005 and underscores
their ongoing focus on technical excellence and customer value.
http://home.businesswire.com/portal/site/google/index.jsp?
ndmViewId=news_view&newsId=20041110005673&newsLang=en
* Borland to Provide UML Support to MS Visual Studio 2005 Team System
Borland joined Microsoft and other industry leaders in announcing
support and future plans for Software Factories, a new industry
approach to improve software development. As part of Borland's support
for Software Factories, the company plans to deliver a domain-specific
modeling solution providing UML capabilities within the Microsoft
Visual Studio 2005 Team System.
http://www.tmcnet.com/usubmit/2004/Oct/1087428.htm
* Borland Focuses on UML Modeling
Borland is breaking up Together ControlCenter for UML modeling into
separate products for developing, designing, and architecting
applications. The move is intended to align Together with the SDO
strategy of providing a disciplined approach to development.
http://www.infoworld.com/article/04/10/25/HNborcontrolcenter_1.html
* IBM and Borland Upgrade Developer Tools
IBM unveiled new Rational developer tools and Borland rolled out the
new version of its Delphi Windows development tool. Both are
maneuvering to infuse their platforms with business process automation
commonly used in other areas of enterprise operations.
http://www.computerweekly.com/articles/article.asp?liArticleID=134236
* Native Win32 and .Net Framework Support for New Delphi
Delphi, the grand-daddy of visual programming environments, has been
updated. Delphi 2005 works with both Win32 and .Net frameworks, and
also supports Microsoft's C# as well as the Delphi language itself.
http://www.pcpro.co.uk/news/64469/
native-win32-and-net-framework-support-for-new-delphi.html
Other / Misc Sites
==================
* The Daily WTF: Curious Perversions In Information Technology
The Daily WTF presents scary code examples. If you are looking for a
good laugh visit the site, I just hope your code is not there! :)
http://thedailywtf.com/
________________________________________________________________________
Irongut's Delphi Pages
Dedicated to programming with Borland Delphi and Kylix. We have articles
on programming, Borland and Delphi news, source code and components to
use in your applications and more. >> http://www.paranoia.clara.net/ <<
________________________________________________________________________
YOU CAN HELP US
We need your help to keep this newsletter going and growing. You can
help by referring the newsletter to your colleagues:
http://www.latiumsoftware.com/en/pascal/delphi-newsletter.php
Or you can help by voting for us in some or all of these rankings to
give more visibility to our web site and thus increase the number of
subscriptions to this newsletter:
http://www.programmingpages.com/?r=latiumsoftwarecomenpascal
http://top100borland.com/in.php?who=20
It's just a few seconds for you that REALLY mean a lot to us.
Don't forget we also need articles and there are prizes available for
contributions. All articles will be considered but we are particularly
interested in articles about Kylix because there is so little available
online to help Kylix developers. Send articles to:
<pascal-newsletter-owner@yahoogroups.com>
We are also looking for shareware authors who would like to offer their
components or applications as prizes for articles in the newsletter. In
return you will be promoted in the newsletter and on the Latium Software
and Irongut's Delphi Pages websites. For more info contact:
Dave Murray <irongut at vodafone dot net>
________________________________________________________________________
If you haven't received the full source code examples for this issue,
you can get them from http://www.latiumsoftware.com/en/file.php?id=p52
________________________________________________________________________
This newsletter is provided "AS IS" without warranty of any kind. Its
use implies the acceptance of our licensing terms and disclaimer of
warranty you can read at http://www.latiumsoftware.com/en/legal.php
where you will also find a note about legal trademarks. Articles are
copyright of their respective authors and they are reproduced here with
their permission. You can redistribute this newsletter as long as you do
it in full (including copyright notices), without changes, and gratis.
________________________________________________________________________
Main page: http://www.latiumsoftware.com/en/pascal/delphi-newsletter.php
Group Home: http://groups.yahoo.com/group/pascal-newsletter/
Subscribe: pascal-newsletter-subscribe@yahoogroups.com
Unsubscribe: pascal-newsletter-unsubscribe@yahoogroups.com
Problems with your subscription? pascal-newsletter-owner@yahoogroups.com
________________________________________________________________________
Latium Software: http://www.latiumsoftware.com/en/index.php
Irongut's Delphi Pages: http://www.paranoia.clara.net/
Copyright 2004 by Ernesto De Spirito + Dave Murray. All rights reserved.
________________________________________________________________________
|