You are on page 1of 8

Pascal Newsletter #10 - 12-NOV-2000

INDEX

1. A FEW WORDS FROM THE EDITOR


2. MYSQL
- WHAT IS MYSQL?
- MYSQL LICENSE
- DELPHI AND MYSQL
- ODBC
- LIBMYSQL.DLL
- WINZEOS
3. "POST-IT." SIZABLE WINDOWS WITHOUT BORDER OR TITLE
- WHY A BORDERLESS AND TITLELESS FORM?
- LET'S GET STARTED
- MANAGING A FORM WITHOUT BORDERS OR TITLE BAR
- AN INVISIBLE MAIN FORM
- IT'S NOT A BUG, IT'S A FEATURE
- POP-UP MENU
4. LINKS

________________________________________________________________________

1. A FEW WORDS FROM THE EDITOR

Those of you who follow the Developers Newsletter probably have read
that -due to work reasons- that newsletter will go monthly.
Nevertheless, I'll strive to keep releasing the Pascal Newsletter more
or less twice a month as I've been doing so far, though I would really
appreciate some help.

You can help keep this newsletter going by contributing articles about
Delphi programming. You will retain the copyright of all the material
you submit to us, but you should grant us a permanent non-revocable
royalty-free permission to translate and publish your article (in its
original form and translated) as long as we do it in full (including
your copyright notice and author information you submit to us for the
purpose of being published, like email address, web site, educational
institution, etc.), without modifications and free of charge. The
newsletters are published by email and at our web site, and each issue
is licensed to be copied and reproduced by anyone as long as it is done
in full (including copyright notices and authors' information), without
modifications and free of charge. If you don't agree to these terms, we
can talk about publishing your articles in our web site (not in a
newsletter) under your own licensing terms.

TAKE THIS OPPORTUNITY TO STAND OUT FROM YOUR COLLEAGUES AND TO ADD A
PUBLISHED ARTICLE TO YOUR CURRICULUM VITAE. WE GIVE CERTIFICATES.

By the way, in this issue I'm glad to present the first contributed
article, which has also been published in our web site:

* "Post-it". Sizable windows without border or title


http://www.latiumsoftware.com/en/articles/00002.php

Changing subjects, there are a couple of new Delphi tips in our web
site:

* How to close another application?


http://www.latiumsoftware.com/en/delphi/00034.php

* How to start an application as an icon in the system tray?


(With full source code)
http://www.latiumsoftware.com/en/delphi/00035.php
Regards,

Ernesto De Spirito
eds2004 @ latiumsoftware.com

________________________________________________________________________

JfControls Library. Multi-language. Multi-appearance. Skins. Privileges.


More than 40 integrated and customizable components. Impressive GUI.
Centralized resources administration. Multiple programming problems
solved. For Delphi 3-7 and C++ Builder 3-6. http://www.jfactivesoft.com/
________________________________________________________________________

2. MYSQL

WHAT IS MYSQL?
==============

MySQL is a reliable, fast, compact, powerful and multi-platform multi-


threaded open-source database server. In my opinion it is one of the
best products of the Open Source Community and its major weakness is
that it doesn't support subqueries (although work is in progress to add
this necessary feature). You can find more information and download it
from the official web site: http://www.mysql.com

MYSQL LICENSE
=============

First of all, I would like to thank Antti Halonen <antti@mysql.com> for


very kindly answering a long email regarding licensing issues.

MySQL is licensed under the terms of the GNU General Public License. It
is free for internal use and for ISPs. For example it is free if you use
it for software development or for companies that may use it as a
database server, and it is also free if you develop a tailor-made
application for a client (it is still considered internal use for both
parties).

The problem arises when you plan to distribute commercial applications


that need MySQL to run (embedded use). Under the terms of the GPL, these
applications should also be distributed as GPL. If you don't want to
distribute them as GPL, you can purchase a commercial license for each
application and server machine running MySQL. For example, if you sell
100 licenses of an application "A" and 50 licenses of an application "B"
to the same client, to be used in a network where your applications will
use 10 MySQL servers running in the same machine, then you should buy
only just two licenses to be able to sell your applications to this
customer because there is only one server machine (no matter how many
MySQL servers it runs) and two applications (no matter how many licenses
of each one you sell), so there are only two "application-server"
combinations (and therefore only two licenses needed):

Application "A" - Server 1


Application "B" - Server 1

A single license costs $200 (USD), and you can buy many licenses
before actually using them to take advantage of important discount
prices.

You can distribute a non GPL application that uses MySQL without paying
a license if the use of MySQL is not required (i.e. if the application
can alternatively do the same stuff using another database system,
server, driver or whatever).
DELPHI AND MYSQL
================

Basically, there are two ways of accessing a MySQL database from a


Delphi application: using an ODBC driver or the libmysql.dll library.

ODBC
----

In the MySQL web site you can find the MySQL ODBC driver for Windows:

http://www.mysql.com/downloads/api-myodbc.html

After installing this driver you can use the BDE Data Access components
or the ADO components to access tables or to perform queries on a MySQL
database.

To use ODBC, first you should create a DSN using the ODBC Data Sources
applet of the Control Panel. For example, I created a DSN named
MySQL_Test and configured it to log in as 'root' in the MySQL server
located at 'localhost' (you can connect to a remote server using its IP
address or its domain name) and open the 'mysql' database.

In a Delphi program you would have to use a TDatabase component if you


don't want the BDE to show the standard login prompt. You have to set
minimally the following properties:

AliasName = 'MySQL_Test'
DatabaseName = 'MySQL_Test'
LoginPrompt = False

In a TTable or TQuery component you have to set the DatabaseName


property to 'MySQL_Test' and that would be it.

The advantage of using ODBC is that you can use the standard Borland
Datasets, and the disadvantage is that you have to go thru two layers to
get to the MySQL server (the BDE and the ODBC driver), although it must
be said that even with ODBC, MySQL is still faster than other database
servers.

LIBMYSQL.DLL
------------

You can also access a MySQL server using the libmysql.dll library. This
file doesn't come with the standard MySQL installation, but you can
download it from:

http://www.fichtner.net/delphi/mysql.delphi.phtml

You should also download the mysql.pas file which is a Delphi a unit
that contains the type declarations for using this library. You need to
include this unit in the uses clause of any unit from which you want to
call the functions contained in the library.

The following example opens a connection to MySql server, opens a


database, performs a query and stores the result in a StringGrid, and
finally closes the connection.

uses ..., mysql;

procedure TForm1.Button1Click(Sender: TObject);


var
mysqlcon: TMySQL; // MySQL-connection structure
presults: pmysql_res; // Pointer to a results structure
prow: pmysql_row; // Pointer to a row structure
pfields: PMYSQL_FIELDS; // Pointer to a fields array
i, j: Integer; // Counters
begin
// Connect to the server
mysql_connect(@mysqlcon, 'localhost', 'root', '');
if mysqlcon.net.last_errno <> 0 then begin
ShowMessage (Trim(mysqlcon.net.last_error));
exit;
end;
// Open the mysql database
if mysql_select_db(@mysqlcon, 'mysql') <> 0 then begin
mysql_close(@mysqlcon); // Disconnect
ShowMessage('Couldn''t open mysql database');
exit;
end;
presults:= nil;
try
// Send the query to the server and get the results
mysql_query(@mysqlcon, 'SELECT * FROM user');
presults := mysql_store_result(@mysqlcon);

// Set the size of the grid


StringGrid1.ColCount := presults^.field_count;
StringGrid1.RowCount := presults^.row_count + 1;

// Fill the grid header with the fields' names


pfields := presults^.fields;
for j := 0 to presults^.field_count -1 do
StringGrid1.Cells[j, 0] := pfields^[j].name;

// Fill the grid


for i := 1 to presults^.row_count do begin
prow := mysql_fetch_row(presults);
for j := 0 to presults^.field_count -1 do
StringGrid1.Cells[j, i]:= prow^[j];
end;
finally
mysql_free_result(presults); // Release memory
mysql_close(@mysqlcon); // Disconnect
end;
end;

As you can see, it's quite complicated, and this constitutes the main
(and I would say only, but very important) disadvantage of using the
libmysql.dll library. The advantages are that you have full control,
that it's faster than using ODBC, and that it doesn't requiere the BDE.
It would be nice to have a TDataset descendant that encapsulates the
libmysql.dll API...

WINZEOS
-------

These components exist, allowing us to access a MySQL server using


standard data controls without using BDE/ADO + ODBC. You can find them
here:

http://www.zeos.dn.ua

The package is distributed under the terms of the GNU General Public
License, but as we explained you can use it freely for "internal use",
including the development of tailor-made applications.

________________________________________________________________________

3. "POST-IT." SIZABLE WINDOWS WITHOUT BORDER OR TITLE


Copyright (c) 2000 Alirio Gavidia <alirio@gavidia.org>

To see more of my articles visit:

Programación Orientada en Delphi (site in Spanish)


http://www.gavidia.org/pod/

Translated to the English language by Ernesto De Spirito with the


author's permission.

WHY A BORDERLESS AND TITLELESS FORM?


====================================

Four are the fundamental facts in the present essay: The first of them
is the existence of programs that mimic Post-it (those little sticky
pages that come in notebooks and flood offices with flashy colors).
Second, the use of certain undocumented Windows function to drag forms.
Third, the problem of how to create an application where the main form
is not visible. And fourth, using the Windows task bar.

The programs that mimic Post-it I take as reference are mainly TurboNote
in Windows and the one of KDE in Linux. Both programs are easily
acquirable and do more than the one I present here. However, I consider
this a good teaching example.

It comes to my mind another program that presents itself without title:


the round (analog) clock that comes with Power Toys for Windows. It will
be left for a future article.

LET'S GET STARTED


=================

The obvious is to imitate a post-it note in some way. The first thought
is a form with a title bar without the usual buttons (minimize,
maximize, etc.) and completely with a plain color. This alternative is
possible and requires a bit specialized Windows management. In
particular I have chosen a more economic alternative regarding code (or
at least that's what I think); and this is eliminating the title bar and
form borders (like you would do in a "splash-screen") and place a panel
and a memo in a form, the first aligned to top and the second to the
client area.

MANAGING A FORM WITHOUT BORDERS OR TITLE BAR


============================================

The form with just a panel and a memo will respond without problems to
keyboard actions, but it is obvious it won't respond to mouse drags and
size changes with the mouse (without borders from where to hold it). The
drag is resolved with an undocumented action, at least that's how it was
some time ago, thru the message SysCommand. The line shown here,
executed from a form, places it in drag state.

Perform(wm_SysCommand, $f012, 0)

The matter with the messages doesn't get limited to this. The resize
modes are also defined that way. For this purpose we defined a set of
constants with the appropriate values starting from $f012.

sc_DragMove = $f012;
sc_Leftsize = $f001;
sc_Rightsize = $f002;
sc_Upsize = $f003;
sc_UpLeftsize = $f004;
sc_UpRightsize = $f005;
sc_Dnsize = $f006;
sc_DnLeftsize = $f007;
sc_DnRightsize = $f008;

NOTE: If you wonder where these values came from, well, what can I
say... I got to know the first one by a Marco Cantú book called "Delphi
Developers' Handbook", the rest came out from trial and error. Let me
tell you that $f040 produces a disastrous result. Also $f020 and $f030
minimize and maximize respectively, which is not necessary for our
application. I don't know if any of this works outside Windows 98.

Additionally, in the MouseDown event of the panel and the memo, where we
send the messages, it is necessary to call ReleaseCapture before sending
the indicated messages.

I won't extend much with the code. It's easier to analyze it from Delphi
than from an HTML page or a DOC. But notice that it has to be
distinguished where a click happened in the panel to know if it is
required to resize or just drag the form. Something similar happens with
the memo for the resize of the bottom and lateral sides.

procedure TfrmNota.Panel1MouseDown(
Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);

begin
ReleaseCapture;
if y<2 then
begin
if x<4 then
Perform(wm_SysCommand, sc_UpLeftsize, 0)
else if x>(Panel1.ClientWidth-4) then
Perform(wm_SysCommand, sc_UpRightsize, 0)
else
Perform(wm_SysCommand, sc_UpSize, 0)
end
else
Perform(wm_SysCommand, sc_DragMove, 0)
end;

sources are part of this article and you will be able to see the
note working in detail. In the attached example, apart from the mouse
event handling we make use of the Windows Registry to store information
relative to the note itself (like its position, font type and color). I
presume that if you understand what we have done up to this point, you
don't need explanations about the use of the Windows Registry (anyway,
its use seems to be well documented in the Delphi Help, and there are
examples and information about it in the Internet).

AN INVISIBLE MAIN FORM


======================

When I made this program I hadn't though of a really silly problem. The
user shall be able to create and destroy notes, but he can't destroy the
main form because this finishes the application. Well, then simply with
not showing the main form it should suffice. If you want to understand
this silly problem create an application in which apart from the main
there exists a secondary form; then make the application start showing
only the secondary form. My attempts resulted in failure. Now I know
this gets accomplished with

Application.ShowMainForm := False;

in the main program before creating the forms, but back then I didn't
know it and I took advantage of the problem to give it an original
solution...
IT'S NOT A BUG, IT'S A FEATURE
==============================

Thinking around the matter, the solution was converting the main form in
a splash screen that lasts a certain amount of time and then hides. This
code gets executed in a timer:

procedure TfrmMain.Timer1Timer(Sender: TObject);


begin
SaveNotes(Sender);
if not oculto then // if not hidden
begin
oculto := True;
ShowWindow(Handle, SW_HIDE);
ShowWindow(Application.Handle, SW_HIDE);
SetWindowLong( Application.Handle, GWL_EXSTYLE,
GetWindowLong(Application.Handle, GWL_EXSTYLE)
or WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);
ShowWindow(Application.Handle, SW_SHOW);
end
end;

With this, the main form gets hidden (the next line right after the
assignment of the "oculto" (hidden) variable, that by the way is False),
and also the presence of the application in the task bar.

The rest of the code is relatively simple and contains some routines to
save and restore the content and configuration of the notes (the first
to disk and the second to the Registry). I believe it doesn't deserve a
deep discussion and therefore I leave to the reader the interpretation
of the routine.

The project as such contains five forms:

* note, is the note with the panel and the memo.


* GenConfig, is the configuration form of the application, currently
only configures formats and counter of the clock.
* Config, note configuration (color, alignment and fonts)
* Main, is the main form, apart from this it works as a splash screen.
* Acerca (About), program version.

As a separate comment, note that due to the presence of a Timer it is


possible to force an "auto save" for the text in the notes. This is
achieved going thru all the forms of type note and saving their contents
from the memo. The routine named SaveNotes is executed from the timer
(having the precaution of not saving what hasn't changed). Each note has
the public variable Changed that is modified when saved and in the
OnChange event of the memo.

POP-UP MENU
===========

The application doesn't have a main menu because it doesn't have a main
form. All actions different than interaction with the memo field and
mouse movements are done by pop-up menus. There are two: one in the note
and one in the icon of the task bar (next to the clock). For this one we
used the RX. Therefore at least for this version you will need to have
sources. If you don't know them, them you should do it, they are free
("freeware") and very good.

RX Library Web Site:


http://www.rxlib.com
Authors:
Fedor Kozhevnikov (fkozh@iname.com)
Igor Pavluk (igorp@mail.com)
Serge Korolev (korolev@usa.net)
--------------------------

The source code that accompanies this article can be downloaded from:

http://www.latiumsoftware.com/download/h-notes.zip

NOTE: The comments and many names are in Spanish. Sorry...

________________________________________________________________________

4. LINKS

* VCL Components - Searchable collection of more than 4000 Delphi and


C++ Builder freeware and shareware components
http://vclcomponents.com/

* The Delphi Search Engine - The Delphi search engine indexes


components, documents, tips, tricks and any Delphi resource in the
web. A Directory of delphi sites is also available.
http://www.delphiseek.com/

* delphi3000 - A knowledge platform for Delphi developers including


articles, code-snippets, forum, components, tips, tricks, DLL,
TreeView, XML, ADO, Internet, Web, GUI...
http://www.delphi3000.com/

________________________________________________________________________

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.sandbrooksoftware.com/cgi-bin/TopSite2/rankem.cgi?id=latium
http://news.optimax.com/delphi/links/links.exe/click?id=70C517ECAE6E
http://www.programmingpages.com/?r=latiumsoftwarecomenpascal
http://www.top219.org/cgi-bin/vote.cgi?delphi&83
http://top100borland.com/in.php?who=20
http://top200.jazarsoft.com/delphi/rank.php3?id=latium
http://213.65.224.200/cgi-bin/toplist.cgi/hits?Id=80

It's just a few seconds for you that REALLY mean a lot to us.

________________________________________________________________________

If you haven't received the full source code examples for this issue,
you can get them from http://www.latiumsoftware.com/download/p0010.zip
________________________________________________________________________

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.
________________________________________________________________________

You might also like