Pascal Newsletter #4
INDEX
1. A FEW WORDS FROM THE EDITOR
2. GETTING THE ICON OF AN APPLICATION OR DOCUMENT
ExtractAssociatedIcon
FIND FILE: Adding icons
3. ERRATA
4. DETERMINING IF THERE IS AN ACTIVE CONNECTION TO THE INTERNET
5. DELPHI TUTORIALS
________________________________________________________________________
1. A FEW WORDS FROM THE EDITOR
I'm happy to announce that soon we will have our own domain name and
hopefully we will be moved to our new site by next week. We are going
commercial, and this means in the future there will be ads in the web
pages to help pay the bills and eventually we will have to include a
little ad in this newsletter, but we will try to keep it ad-free for as
long as we can.
Regards,
Ernesto De Spirito
eds2008 @ 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-2006 & C++ Builder 3-6. http://www.jfactivesoft.com
________________________________________________________________________
2. GETTING THE ICON OF AN APPLICATION OR DOCUMENT
ExtractAssociatedIcon
=====================
To get the icon of an application or document we can use this API
function declared in the ShellAPI unit:
function ExtractAssociatedIcon(hInst: HINST; lpIconPath: PChar;
var lpiIcon: Word): HICON; stdcall;
hInst: The application handle. This value is contained in the predefined
variable HInstance.
lpIconPath: A pointer to a character buffer that should contain a null
terminated string with the full path name of the application,
library (DLL) or document. If it is a document, the function will
place there the full pathname of the associated application from
where the icon was extracted, so we should allocate a buffer
large enough.
lpiIcon: The icon index (the first icon in the file has an index of 0).
If lpIconPath specifies a document, then lpiIcon is set by the
function (that's why it is passed by reference) to the index
position of the actual icon taken from the associated executable
(defined in the file association).
Return value:
If the function fails, it returns 0. If it succeeds, it returns an icon
handle, which is an integer value Windows uses to identify the allocated
resource. It is not necessary to call the API DestroyIcon to release the
icon since it'll be deallocated automatically when the application
finishes, although you can do it if you want.
Now, what do we do with the icon handle? Normally what we want is an
icon, namely and instance of the TIcon class. All we have to do is
create a TIcon object and assign this handle to its Handle property.
If later we assign the Handle property to another value, the previous
icon will be automatically be released. The same happens if the TIcon
object is freed.
FIND FILE: Adding icons
=======================
Continuing the work with the Find File application we use to show some
programming tips, this time we will add the file icons in the ListView
control.
The first thing we'll do is placing an ImageList on the form (normally
it's located in the Win32 palette) and then we'll assign it to the
SmallImages property of ListView1.
Now it's time to add code in the AddFileName method of TThread1. We need
four more variables:
Icon: TIcon;
IconIndex: word;
Buffer: array[0..2048] of char;
IconHandle: HIcon;
And then we add the following code (for example right after the line
"ListItem.Caption := FileName;"):
StrCopy(@Buffer, PChar(Location + FileName));
IconIndex := 0;
IconHandle := ExtractAssociatedIcon(HInstance, Buffer, IconIndex);
if IconHandle <> 0 then begin
Icon := TIcon.Create;
Icon.Handle := IconHandle;
ListItem.ImageIndex := OwnerForm.ImageList1.AddIcon(Icon);
Icon.Free;
end;
Finally we empty the ImageList right after we empty the ListView in the
Initialize method of TThread1, so it doesn't grow "indefinitely":
OwnerForm.ImageList1.Clear;
Now you can try the example to see it working. As usual, the full source
code is available in our web site:
http://www.latiumsoftware.com/en/file.php?id=p04
________________________________________________________________________
3. ERRATA
In the last issue we showed how to take coordinates relative to a
control and make them relative to the screen adding to them the form's
position and the control's position in the form. This doesn't account
correctly for the borders and title bar of the form, and if the control
was inside another container we would have to add its coordinates too...
The easy way is using the property ClientOrigin that all descendants of
TControl have and forget about all this. For instance, in our
ListView1MouseDown procedure, instead of
PopupMenu1.Popup(
Left + ListView1.Left + X + 5,
Top + ListView1.Top + Y + 20);
we should use
PopupMenu1.Popup(
ListView1.ClientOrigin.X + X,
ListView1.ClientOrigin.Y + Y);
________________________________________________________________________
4. DETERMINING IF THERE IS AN ACTIVE CONNECTION TO THE INTERNET
It is easy to know if you are connected to the net. Basically all you
have to do is checking the first byte of the data under the following
Windows Registry key value:
+ HKEY_LOCAL_MACHINE
+ System
+ CurrentControlSet
+ Services
+ RemoteAccess
--> Remote Connection
This data element consists of four bytes, so we use ReadBinaryData
instead of the ReadString method we used when we gave an introduction
to the Windows Registry in the second issue of the former Delphi
Newsletter. If the first of these bytes equals 1, you are connected to
the net, otherwise not (it should then be 0).
The following function returns True if you are connected to the net:
uses Registry, WinSock;
function InternetConnection: boolean;
var
Reg: TRegistry;
RemoteConnection: array [0..3] of byte;
Error: boolean;
HostName: array[0..63] of char;
WSData: TWSAData;
begin
Result := False;
Error := False;
Reg := nil;
try
Reg := TRegistry.Create(KEY_QUERY_VALUE);
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKeyReadOnly('\System\CurrentControlSet\Services\'
+ 'RemoteAccess') then begin
try
Reg.ReadBinaryData('Remote Connection', RemoteConnection,
SizeOf(RemoteConnection));
if RemoteConnection[0] = 1 then Result := True;
except
Error := True;
end;
Reg.CloseKey;
end;
except
Error := True;
end;
Reg.Free;
if Error then
// Try another way of finding if there is a connection
if WSAStartup($200, WSData) = 0 then begin
GetHostName(HostName, SizeOf(HostName));
if GetHostByName(HostName) <> nil then Result := True;
WSACleanup;
end;
end;
If an error occurs while accessing the Registry, the function tries an
alternative method of detecting an internet connection using the WinSock
APIs.
WSAStartup initiates the Windows Sockets service and in this case we
request up to version 2.0 if possible. WSData is a record where this
function will put some information about the Windows Sockets DLL. If
WSAStartup returns 0 (meaning it succeeded) we call GetHostName to get
the name of our computer, that we use it to call GetHostByName, that in
turn returns a pointer to a record with information about the host
address/es, or Nil if there is no connection, so we use this value to
determine whether there is a connection. Once we are done with the
Windows Sockets we should close the session by calling WSACleanup.
________________________________________________________________________
5. DELPHI TUTORIALS
One of the things we are most asked is information about tutorials on
Delphi programming, so here are a few links:
* Astentech Delphi Tutorial List
http://www.astentech.com/tutorials/Delphi.html
* Delphi Tutorial
http://privat.schlund.de/b/bossung/delphi/tutorial_multipage.html
* The Software Developers Pages
http://www.beensoft.nl/sdp/
* Delphi and Pascal programming tutorials
http://ourworld.compuserve.com/homepages/TK_Boyd/Tut.htm
* DelphiLand: programming courses, tips, sources, utilities
http://www.festra.com/
* Frank's Delphi Lessons
http://www.svn.net/ffortino/
________________________________________________________________________
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.
________________________________________________________________________
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=p04
________________________________________________________________________
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 page: http://groups.yahoo.com/group/pascal-newsletter/
Subscribe/join: pascal-newsletter-subscribe@yahoogroups.com
Unsubscribe/leave: pascal-newsletter-unsubscribe@yahoogroups.com
Problems with your subscription? eds2008 @ latiumsoftware.com
________________________________________________________________________
Latium Software http://www.latiumsoftware.com/en/index.php
Copyright (c) 2000 by Ernesto De Spirito. All rights reserved.
________________________________________________________________________
|