04.08.2013 Views

dFPUG.fll Version 3 – Zip, Scan, and more - dFPUG-Portal

dFPUG.fll Version 3 – Zip, Scan, and more - dFPUG-Portal

dFPUG.fll Version 3 – Zip, Scan, and more - dFPUG-Portal

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>dFPUG</strong>.<strong>fll</strong> <strong>Version</strong> 3 <strong>–</strong> <strong>Zip</strong>,<br />

<strong>Scan</strong>, <strong>and</strong> <strong>more</strong><br />

Venelina Jordanova, Uwe Habermann, Erich Todt<br />

The <strong>dFPUG</strong>.<strong>fll</strong> has grown up. The little FLL with<br />

functions for compressing <strong>and</strong> decompressing files<br />

has become an ample collection of functions indispensable<br />

for many purposes. FoxPro developers<br />

are offered capabilites hitherto unknown.<br />

The History<br />

The first version of the <strong>dFPUG</strong>.<strong>fll</strong> was published<br />

in January 2004. It provided a simple ZIP functionality.<br />

Owing to the huge feedback from developers,<br />

the second version was released in March 2005.<br />

That one made many further features of the ZIP<br />

algorithm available.<br />

Now the third version of the <strong>dFPUG</strong>.<strong>fll</strong> provides<br />

substantially <strong>more</strong> functions from various<br />

functional areas.<br />

In its first two versions, the <strong>dFPUG</strong>.<strong>fll</strong> contained<br />

merely functions for creating <strong>and</strong> extracting ZIP<br />

archives. Of course those functions stay available.<br />

The ZIP functions have been described extensively<br />

in the two previous articles. Therefore they won’t<br />

be treated here in depth.<br />

New Functions<br />

The new functions may be divided into four functional<br />

areas.<br />

At first, there are scanning functions. They<br />

permit to control TWAIN scanners from VFP<br />

applications <strong>and</strong> to scan images.<br />

The second functional area comprises Internet<br />

<strong>and</strong> Windows API programming. Sometimes you<br />

need functions which convert a string in such a<br />

manner that it can be used as a parameter in a URL.<br />

Now there is a function for that purpose, <strong>and</strong> of<br />

course another one to execute the conversion the<br />

other way round.<br />

In a further area, entries can be added to the<br />

Windows Event Viewer. A real alternative to own<br />

log files. These functions become particularly<br />

interesting if you develop COM servers or Windows<br />

services which shall log information about their<br />

current state or errors.<br />

And finally we have a set of functions that<br />

provide Windows system information.<br />

Dependencies<br />

The new <strong>dFPUG</strong>.<strong>fll</strong> has been written in C like its<br />

previous versions.<br />

MSVC71.dll can be registered at the target<br />

machine; if it is not registered, it must reside in<br />

the same folder as the <strong>dFPUG</strong>.<strong>fll</strong>. In both cases the<br />

<strong>dFPUG</strong>.<strong>fll</strong> can be used from any VFP 9 application<br />

from any folder on the target machine.<br />

If a MSVC71.dll is stored in a different folder<br />

<strong>and</strong> is registered there, it will be recognized by the<br />

<strong>dFPUG</strong>.<strong>fll</strong>, <strong>and</strong> it can be used from that folder.<br />

In case you want to use the <strong>dFPUG</strong>.<strong>fll</strong> together<br />

with older versions of VFP, you’ll normally have to<br />

copy the file MSVC71.dll to the target PC.<br />

For the scanning functions the file GDIPLUS.<br />

DLL is needed. Since Windows 98, that file has<br />

been present in every Windows installation, so we<br />

need not worry about it.<br />

For the individual functions, further DLLs or<br />

other files of Windows are required if need be.<br />

Those files are being loaded dynamically during<br />

runtime. Thus, to our advantage, the <strong>dFPUG</strong>.<strong>fll</strong><br />

may in any case be loaded without problems via<br />

the comm<strong>and</strong><br />

SET LIBRARY TO <strong>dFPUG</strong>.<strong>fll</strong><br />

If in using a function a dependent DLL cannot<br />

be loaded, a corresponding return value is yielded.<br />

So the developer need not worry about error<br />

messages due to missing dependencies.<br />

The ZIP functions continue to be contained<br />

unchanged in the FLL, making the new version 3<br />

fully upward compatible to the previous one.<br />

A sample application<br />

Naturally we have a sample application for this<br />

version of the <strong>dFPUG</strong>.<strong>fll</strong>, too. It demonstrates how<br />

to use the functions. Screenshots of the sample app<br />

are shown in the course of this article.<br />

And there are further examples about some of<br />

the functions.<br />

May 2011 FoxRockX Page 1


Figure 1. <strong>–</strong> determining the version number<br />

Functions by categories<br />

The <strong>dFPUG</strong>.FLL provides the following functions.<br />

General<br />

<strong>dFPUG</strong>Initialize<br />

Call at initializing.<br />

<strong>dFPUG</strong>UnInitialize<br />

Call at release.<br />

<strong>dFPUG</strong>Fll<strong>Version</strong><br />

Returns the version number of the <strong>dFPUG</strong>.FLL or<br />

of some dynamically loaded system files.<br />

Compressing or extracting files<br />

Create<strong>Zip</strong>Archive<br />

Serves to create ZIP archive files.<br />

Extract<strong>Zip</strong>Archive<br />

Serves to extract ZIP archive files.<br />

<strong>Scan</strong>ner Support<br />

GetTWAINSources<br />

Display the available scanners.<br />

GetTWAINImage<br />

Trigger the scanning.<br />

Internet<br />

UrlEscape<br />

Converts characters which are not allowed in URLs<br />

into the respective escape sequences (“%xy”).<br />

UrlUnescape<br />

Converts Escape sequences (“%xy”) in a URL into<br />

readable text.<br />

Windows API Programming<br />

GetNullSA<br />

This function returns a pointer to a SECURITY_<br />

ATTRIBUTES structure with a null­security descriptor.<br />

With this function you can, by means of Windows API<br />

functions, create files, create folders, or create kernel<br />

objects etc. with the permission All <strong>–</strong> Full access.<br />

GetWinErrorString<br />

Converts a Win32 oder COM/<br />

OLE error number into the<br />

equivalent error message of<br />

the operating system.<br />

Windows Event Viewer<br />

RegisterEventSource<br />

Adds the necessary entries to<br />

the Windows registry so that<br />

event numbers can be converted<br />

into a message text by the<br />

Event Viewer.<br />

UnregisterEventSource<br />

Deletes entries from the Windows<br />

registry which enter<br />

event numbers into the Event<br />

Viewer.<br />

ReportEvent<br />

Adds an entry to the Windows event list.<br />

Windows System Information<br />

CheckAdminRights<br />

Tells whether the user running the current thread<br />

has adminstrator rights.<br />

ComputerName<br />

Returns the NetBIOS or DNS name of the local<br />

computer.<br />

GetShortPath<br />

Converts a long path name or file name into its<br />

short equivalent (MS DOS 8.3 convention).<br />

IsWinNT<br />

Tells whether the operating system is based on<br />

Windows NT (WinNT, 2000, XP, 2003, Vista).<br />

ShellFolder<br />

This function yields the paths to various Windows<br />

system folders.<br />

UserName<br />

Returns the name of the user or of the security policy<br />

under which the current thread is being executed.<br />

Reference<br />

This chapter introduces all functions in detail with<br />

their parameters <strong>and</strong> return values.<br />

<strong>dFPUG</strong>Fll<strong>Version</strong><br />

Returns the version number of the <strong>dFPUG</strong>.FLL or<br />

of some dynamically loaded system files.<br />

<strong>dFPUG</strong>Fll<strong>Version</strong>([nFormat])<br />

Return value<br />

See table 1.<br />

Parameter<br />

If you don’t provide the optional parameter nFormat,<br />

the return value is identical to the value given in<br />

table 1 under nFormat = 0.<br />

Page 2 FoxRockX May 2011


Table 1. <strong>–</strong> Parameters <strong>and</strong> return values of <strong>dFPUG</strong>Fll<strong>Version</strong><br />

Parameter<br />

nFormat<br />

Data type Return Value Description<br />

0 Character <strong>dFPUG</strong> Funktions- Description <strong>and</strong> complete version number. The output<br />

Bibliothek<br />

does not have a st<strong>and</strong>ardized format. If you want be able<br />

03.00.7071.0 to evaluate a query about the version in a programme,<br />

better call the function with the parameter 4 or 5.<br />

4 Character 03.03.6029.0002 <strong>Version</strong> number in a st<strong>and</strong>ardized format:<br />

MM.mm.YDDD.nnnn<br />

MM<br />

Main version<br />

mm<br />

Minor version<br />

YDDD<br />

Build number<br />

NNNN<br />

Serial number<br />

5 Numeric 300 Numerical version number, calculated by the formula<br />

(100* Main version) + Minor version.<br />

105 Numeric 600 Numerical version number of shlwapi.dll, calculated by<br />

the formula (100* Main version) + Minor version.<br />

The functions UrlEscape() <strong>and</strong> UrlUnescape() require<br />

the file shlwapi.dll version 5.0 or higher. This file is part<br />

of the operating system or is installed with the Internet<br />

Explorer respectively.<br />

205 Numeric 700 Numerical version number of wininet.dll, calculated by<br />

the formula (100* Main version) + Minor version.<br />

The function CrackUrl() requires the file wininet.dll<br />

version 3.0 or higher. This file is part of the operating<br />

system or is installed with the Internet Explorer<br />

respectively.<br />

CheckAdminRights<br />

Tells whether the user excecuting the current thread<br />

has administrator rights.<br />

CheckAdminRights()<br />

Return value<br />

Logical.<br />

Comments<br />

This function only makes sense<br />

with Windows NT­based operating<br />

systems (WinNT, 2000,<br />

XP, 2003, Vista).<br />

In Windows 9x systems<br />

(Win95, 98, ME) the function<br />

always returns .T. because<br />

the operating system does not<br />

support anything we may call<br />

a real administration of user<br />

rights.<br />

To ask for the OS platform,<br />

you can use either IsWinNT()<br />

or the FoxPro function OS(6).<br />

A return value of “2” (Look<br />

out: string!) indicates that it is<br />

a Windows NT­based operating<br />

system.<br />

ComputerName<br />

Returns the NetBIOS name or DNS name of the<br />

local computer.<br />

ComputerName([nFormat])<br />

Return value<br />

Character.<br />

Figure 2. <strong>–</strong> display of the computer name<br />

May 2011 FoxRockX Page 3


Parameter<br />

Return value<br />

nFormat<br />

node<br />

N/A NetBIOS name of the local computer. NetBIOS name of the virtual cluster server.<br />

0 NetBIOS name of the local computer. NetBIOS name of the virtual cluster server.<br />

1 DNS host name of the local computer. DNS host name of the virtual cluster server.<br />

2 DNS domain name of the local computer. DNS domain name of the virtual cluster server.<br />

3 Fully qualified DNS name which uniquely Fully qualified DNS name of the virtual cluster<br />

identifies the local computer.<br />

server.<br />

4 NetBIOS name of the local computer. NetBIOS name of the local computer.<br />

5 DNS host name of the local computer. DNS host name of the local computer.<br />

6 DNS domain name of the local computer. DNS domain name of the local computer.<br />

7 Fully qualified DNS name which uniquely<br />

identifies the local computer.<br />

Fully qualified DNS name of the local computer.<br />

Table 2. - Parameters <strong>and</strong> return values of ComputerName<br />

Parameter<br />

When you call the function without parameters,<br />

it yields the NetBIOS name of the local computer.<br />

If the local Computer is a node in a cluster, the<br />

function will return the NetBIOS name of the virtual<br />

cluster server.<br />

By providing the optional parameter nFormat<br />

you can determine not only the NetBIOS name, but<br />

also the DNS name of the computer, of the host or<br />

of the domain. This applies to Windows 2000 or<br />

higher versions. In the table below you find the<br />

valid values for nFormat <strong>and</strong> the respective return<br />

values. If the local computer is a node in a cluster,<br />

the function yields the value shown in the column<br />

“node”.<br />

In case the name of the computer cannot be<br />

determined in the given format, or if the value for<br />

nFormat is not valid, the function will return an<br />

empty string.<br />

Comments<br />

System requirements: The optional parameter<br />

nFormat is only supported on Windows NT­based<br />

operating systems from Windows 2000 upwards.<br />

With all other operating sysystems (Win95, 98,<br />

ME, NT4) the function produces the FoxPro error<br />

1098 with a matching error message text, e.g.<br />

”This function is not supported by the operating<br />

system”.<br />

Calling this function without the optional<br />

parameter nFormat is supported in all Windows<br />

operating systems on which Visual FoxPro can<br />

run.<br />

You may either use IsWinNT() or the FoxPro<br />

function OS(6) to inquire about the OS platform. A<br />

return value of “2” (Attention: string!) means that it<br />

is a Windows NT­based opearting system.<br />

You can employ the FoxPro function OS(3) to<br />

determine the main version number of the operating<br />

system. E.g. in Windows 2000, OS(3) returns the<br />

string “5”.<br />

DNS names constist of one or several<br />

components, each one up to 63 characters long <strong>and</strong><br />

delimited from each other by periods, for example<br />

“www.dfpug.de”.<br />

A cluster is a group of two or <strong>more</strong> servers (aka<br />

nodes) which cooperate <strong>and</strong> appear in the network<br />

as one single virtual server.<br />

With DNS names, uppercase <strong>and</strong> lowercase<br />

spelling are not discerned.<br />

The fully qualified DNS name is a combination<br />

of the DNS host name <strong>and</strong> the DNS domain name,<br />

written in the form HostName.DomainName. For<br />

instance, if the DNS host name is “corporate­mailserver”<br />

<strong>and</strong> the DNS domain name is “dfpug.<br />

de”, then the fully qualified DNS name will be<br />

“corporate­mail­server.dfpug.de”.<br />

NetBIOS names consist of up to 15 bytes of<br />

OEM characters, <strong>and</strong> as a rule one character equals<br />

one byte. However, some country­specific OEM<br />

characters can be two bytes long.<br />

With NetBIOS names, uppercase <strong>and</strong> lowercase<br />

spelling are in principle not discerned, but<br />

uppercase spelling is preferred, especially so if the<br />

conversion from lowercase to uppercase letters is<br />

dependent on the OEM character set.<br />

The NetBIOS name <strong>and</strong> the DNS host name<br />

depend on each other. Whenever you change the<br />

DNS host name, the NetBIOSname is changed as<br />

well <strong>and</strong> truncated to 15 bytes. E.g. if the DNS name<br />

is “corporate­mail­server”, the NetBIOS name<br />

“corporate­mail­” will result from this.<br />

If you change the name of a computer, you will<br />

have to restart it to let the changes take effect. The<br />

NetBIOS name is read from the Windows Registry<br />

during startup.<br />

Create<strong>Zip</strong>Archive<br />

Serves to create ZIP archives.<br />

Create<strong>Zip</strong>Archive( cPath, cFileSkeleton,<br />

cArchiveFullPathName, cFeedbackFunction,<br />

nCompressionLevel, lResurseSubfolders,<br />

cPassword )<br />

Page 4 FoxRockX May 2011


Figure 3 .<strong>–</strong> Example of creating ZIP archives<br />

Return value<br />

Not defined. Status messages are given via the<br />

FeedBack function.<br />

Parameters<br />

cPath<br />

Character. Path of the folder which is to be archived.<br />

cFileSkeleton<br />

Character. Names of the files to be archived. The<br />

wildcards “?” <strong>and</strong> “*” can be used. Several file<br />

names may be given, separated by semicolon.<br />

Example: “*.dbf;*.fpt;*.cdx”<br />

cArchiveFullPathName<br />

Character. Complete path name <strong>and</strong> file name of<br />

the ZIP archive to be created.<br />

cFeedBackFunction<br />

Character. Name of a function or method which is<br />

called by Create<strong>Zip</strong>Archive() to reveal information<br />

about the progress. This function or method must<br />

be declared thus:<br />

[Object.](<br />

tcCurrentOperatedFile, tnState,<br />

tnAllFilesSize, tnZIPedFilesSize,<br />

tnArchiveCurrentSize ): nResult<br />

tcCurrentOperatedFile<br />

name of the file which is currently being processed.<br />

tnState<br />

Current state:<br />

1. The archive file cArchiveFullPath-<br />

Name already exists.<br />

2. Beginning to add the file tcCurrent-<br />

OperatedFile to the archive.<br />

3. Finish of adding the file tcCurrent-<br />

OperatedFile to the archive.<br />

4. The file tcCurrentOperatedFile could<br />

not be added to the archive.<br />

5. The creation of the archive was complete<br />

<strong>and</strong> has been concluded.<br />

6. The creation of the archive could not<br />

be concluded.<br />

7. No valid path name or file name was<br />

given, or there are no files to be put<br />

into the archive.<br />

tnAllFilesSize<br />

Total size of all files which shall be added to<br />

the archive.<br />

tnZIPedFilesSize<br />

Size of the files that have already been added<br />

to the archive.<br />

tnArchiveCurrentSize<br />

Current size of the created archive file.<br />

nResult<br />

The return value controls the further behaviour of<br />

the function Create<strong>Zip</strong>Archive():<br />

0 The process shall be aborted.<br />

1 The files have been added to the archive.<br />

2 The process is being continued.<br />

nCompressionLevel<br />

The ZIP algorithm permits different levels of compression.<br />

The values ­1 to 9 are allowed. The values<br />

mean:<br />

-1 St<strong>and</strong>ard compression<br />

(identical to the value 6)<br />

0 No compression<br />

1 Maximum speed<br />

6 St<strong>and</strong>ard compression<br />

9 Best compression<br />

lResurseSubfolders<br />

If the value of this parameter is .T., sub­folders<br />

are recursively included. The files selected as<br />

cFileSkeleton are being taken care of in the subfolders,<br />

too.<br />

If the value of this parameter is .F., sub­folders are<br />

not included.<br />

cPassword<br />

Here a password must be put in if the archive shall<br />

be protected. In case you do not need a password<br />

protection, an empty string must be put in here. For<br />

the password, all characters except for CHR(0) are<br />

permissible.<br />

May 2011 FoxRockX Page 5


Comments<br />

As the return value is not defined, you should never<br />

try to evaluate or save the result of this function.<br />

Extract<strong>Zip</strong>Archive<br />

Service to unpack ZIP archive files.<br />

Extract<strong>Zip</strong>Archive( cExtractFilesFolder,<br />

cFileSkeleton, cArchiveFullPathName,<br />

cFeedBackFunction, cPassword )<br />

Return value<br />

Not defined. Status messages happen via the FeedBack<br />

function.<br />

The process could not be finished.<br />

Page 6 FoxRockX May 2011<br />

6.<br />

7.<br />

8.<br />

Reserved.<br />

Invalid password.<br />

tnArchiveFilesSize<br />

Size of the archived files.<br />

tnUnZIPedFilesSize<br />

Size of the files already unpacked.<br />

nResult<br />

The return value controls the further behaviour of<br />

the function Extract<strong>Zip</strong>Archive():<br />

Parameters<br />

0 The unpacking shall be aborted.<br />

cExtractFilesFolder<br />

1 The process shall be continued.<br />

Character. Folder where the unpacked files are<br />

being stored.<br />

2<br />

Overwriting the existing file with the archived<br />

file.<br />

cFileSkeleton<br />

cPassword<br />

Character. Names of the files to unpack. The wildcards Here a password must be put in if the archive is<br />

“?” <strong>and</strong> “*” may be used. Several file names can be protected by a password. In case you do not need<br />

given, separated from each other by semicolons.<br />

a password protection, an empty string must be<br />

Example: “*.dbf;*.fpt;*.cdx”<br />

passed here. For the password, all characters except<br />

for CHR(0) are permissible.<br />

cArchiveFullPathName<br />

Character. Complete path <strong>and</strong> file name of the<br />

archive file to be unpacked.<br />

cFeedBackFunction<br />

Character. Name of a function<br />

or method which is called<br />

by Extract<strong>Zip</strong>Archive() to<br />

yield information about the<br />

progress. This function or<br />

method must be declared as<br />

follows:<br />

[Object.]<br />

(<br />

tcCurrentOperatedFiles,<br />

tnState, tnArchiveFiles-<br />

Size, tnUnZIPed-FilesSize<br />

): nResult<br />

tcCurrentOperatedFiles<br />

Name of the file which is currently<br />

being unpacked.<br />

tnState<br />

Current state:<br />

Comments<br />

As the return value is not defined, you should never<br />

try to evaluate or save the result of this function.<br />

1. The file to be<br />

unpacked does<br />

alerady exist.<br />

2. Begin of the<br />

unpacking of the file<br />

Figure 4. <strong>–</strong> The <strong>Scan</strong> dialogue of the sample application<br />

3.<br />

4.<br />

5.<br />

tcCurrentOperatedFile.<br />

End of the unpacking of the file<br />

tcCurrentOperatedFile.<br />

The file tcCurrentOperatedFile could not be<br />

unpacked.<br />

The process has been finished<br />

successfully<br />

GetTWAINSources<br />

GetTWAINSources(@tcTwainSources) <strong>–</strong> Returns a list<br />

of the available TWAIN devices connected to the<br />

computer.<br />

Return value<br />

0 <strong>–</strong> If the operation has been completed successfully.


nErrorNumber <strong>–</strong> If an error has occurred. Cf the<br />

TWAIN error messages.<br />

Parameter<br />

tcTwainSources <strong>–</strong> A string, passed via a reference. In<br />

this string, a semicolon­delimited list of available<br />

TWAIN devices is returned.<br />

GetTWAINImage<br />

GetTWAINImage(tcFileName, tcFileFormat,<br />

tlUseDefaultTWAINSource, tcTWAINSource,<br />

tlDisplayAdvancedSettingsDialog,<br />

tlDisplayprogressDialog) <strong>–</strong> <strong>Scan</strong>s an image <strong>and</strong><br />

stores it in the file tcFileName.<br />

Return value<br />

0 <strong>–</strong> If the process has been executed successfully.<br />

nErrorNumber <strong>–</strong> if an error has occurred, TWAIN<br />

error message.<br />

Parameters<br />

tcFileName <strong>–</strong> Complete path <strong>and</strong> file name of the file<br />

in which the scanned image shall be stored.<br />

tcFileFormat <strong>–</strong> Name extension of the file format.<br />

The value can be BMP, JPG, GIF, PNG, or TIFF.<br />

When this parameter is empty, the st<strong>and</strong>ard value<br />

is TIFF.<br />

tlUseDefaultTWAINSource <strong>–</strong> If the value is .T., the<br />

default TWAIN device will be used. When this<br />

parameter is empty, the default value .T. is applied.<br />

tcTWAINSource <strong>–</strong> string with the TWAIN source to<br />

be used. If the value of tlUseDefaultTWAINSource is<br />

.F. <strong>and</strong> if the value of the property tcTWAINSource<br />

is empty <strong>and</strong> <strong>more</strong> than one TWAIN device is<br />

connected, a dialogue to choose the TWAIN device<br />

is shown.<br />

tlDisplayAdvancedSettingsDialog <strong>–</strong> When this value<br />

is .T., a dialogue with advanced settings shows. Depending<br />

on the TWAIN source used, this dialogue<br />

may possibly not be available. If this parameter is<br />

empty, the default value .F. is used.<br />

tlDisplayprogressDialog <strong>–</strong> When this value is .T., a<br />

progress bar is displayed. If this parameter is empty,<br />

the default value .T. is used.<br />

GetNullSA<br />

Returns a pointer to a SECURITY_ATTRIBUTES<br />

structure with a null­security descriptor.<br />

You can pass this pointer as a LPSECTURITY_<br />

ATTRIBUTES parameter to Windows API functions<br />

in order to create files, folders, or kernel objects etc.<br />

to which all users have access without limitation<br />

(Permissions: Everyone <strong>–</strong> Full Control).<br />

GetNullSA([lInheritH<strong>and</strong>le])<br />

Return value<br />

Numeric.<br />

Parameter<br />

In case you call the function without a parameter,<br />

the element bInheritH<strong>and</strong>le of the SECURITY_<br />

ATTRIBUTES structure created is initialized as<br />

FALSE.<br />

lInheritH<strong>and</strong>le<br />

lInheritH<strong>and</strong>le Description<br />

.F. The element bInheritH<strong>and</strong>le of<br />

the SECURITY_ATTRIBUTES<br />

structure created is initialized as<br />

FALSE.<br />

.T. The element bInheritH<strong>and</strong>le of<br />

the SECURITY_ATTRIBUTES<br />

structure created is initialized as<br />

TRUE.<br />

The exact meaning of the element bInheritH<strong>and</strong>le<br />

is mostly different among the individual Windows<br />

API functions. You will find further information in<br />

the documentation of the respective Windows API<br />

functions.<br />

Example of usage<br />

A typical example would consist in using FoxPro as<br />

a debugger to which other applications are sending<br />

information. As a communication interface you<br />

could use e.g. a Named Pipe or a FileMapping<br />

object. The latter is being created by the debugger<br />

with a null­security descriptor; thus it can be opened<br />

to write by the single applications, independent of<br />

their user context.<br />

Comments<br />

The memory reserved by this function is released<br />

automatically upon the release of the <strong>dFPUG</strong>.FLL.<br />

It can constitute a considerable security risk to<br />

permit every user full control of a file, a folder, or<br />

a kernel object. Therefore you should only consider<br />

doing this in particular cases <strong>and</strong> deliberate it<br />

thoroughly.<br />

You should never store the return value of this<br />

function in a variable, but always call this function<br />

<strong>and</strong> pass the result directly to your Windows API<br />

function.<br />

If you declare a Windows API function in<br />

FoxPro with DECLARE­DLL, you have to declare<br />

the data type Integer for lpSecurityAttributes.<br />

If you pass 0 (zero) for lpSecurityAttributes to a<br />

Windows API function, this usually means that the<br />

file to be created (or the folder or the kernel object)<br />

takes the security attributes of the current thread or<br />

the superior object. But in any case it does not mean<br />

that the permissions are set to Everyone. Further<br />

information you will find in the documentation for<br />

the respective Windows API functions.<br />

In practice you can mostly leave out lInheritH<strong>and</strong>le<br />

<strong>and</strong> thus initialize the element bInheritH<strong>and</strong>le of the<br />

SECURITY_ATTRIBUTES structure with FALSE.<br />

May 2011 FoxRockX Page 7


Example<br />

In the following example we create two new folders,<br />

one of them with the st<strong>and</strong>ard permissions <strong>and</strong> the<br />

other with Everyone <strong>–</strong> Full Control.<br />

SET LIBRARY TO dfpug.<strong>fll</strong><br />

DECLARE Integer CreateDirectory ;<br />

IN WIN32API ;<br />

String lpPathName, ;<br />

Integer lpSecurityAttributes<br />

*-- Create a folder with st<strong>and</strong>ard access<br />

*-- rights:<br />

CreateDirectory(SYS(2015)+”_St<strong>and</strong>ard”,0)<br />

*-- And now a folder with full access for all<br />

*-- users:<br />

CreateDirectory(SYS(2015)+”_<br />

Everyone”,GetNullSA())<br />

You can check the difference between the two<br />

folders by marking one in the Windows Explorer<br />

<strong>and</strong> a right mouse click to open the Properties in the<br />

context menu.<br />

Note<br />

In some newer operating systems (like Windows<br />

XP Professional without domain membership), in<br />

order to see the above mentioned tabs Sharing <strong>and</strong><br />

Security in the Properties window, you will have<br />

to deactivate “use simple file sharing” in the folder<br />

options in the Windows Explorer.<br />

GetWinErrorString<br />

When an error occurs, many Windows API functions<br />

<strong>and</strong> COM/OLE objects return a numerical value<br />

which represents an error code or a status code,<br />

though in some cases it can mean a warning or<br />

a message about a successful operation (e.g. 0 =<br />

ERROR_SUCCESS).<br />

This function converts such a Win32 or COM/<br />

OLE error number to the corresponding error<br />

message of the operating system. Apart from this,<br />

up to three parameters can be passed which are<br />

inserted in place of the wildcard characters [1], [2],<br />

<strong>and</strong> [3], provided that the message text contains<br />

these wildcards.<br />

Note: The Win32 error numbers are completely<br />

different from FoxPro or TWAIN error numbers as<br />

regards their scope <strong>and</strong> their meaning. They must<br />

not be mixed up.<br />

GetWinErrorString( nErrorCode [ , [ cParam1]<br />

[, [cParam2] [, cParam3 ]]] )<br />

Return value<br />

Character.<br />

If the operating system provides no error message<br />

for nErrorCode , the function returns the empty<br />

string.<br />

Some Win32 error messages contain wildcards<br />

to be replaced by application­specific strings, e.g.<br />

nErrorCode = 34 (ERROR_WRONG_DISK). If the<br />

optional parameters cParam1 to cParam3 are not<br />

given, the returned message text contains the<br />

wildcards, e.g. [1], [2] or [3].<br />

Parameters<br />

nErrorCode<br />

Numeric Win32 error number between ­2147483648<br />

<strong>and</strong> 2147483647 (0x00000000­0xFFFFFFFF). COM/<br />

OLE error numbers are by definition negative<br />

number values which can also be stated as<br />

hexadecimal. For example, E_OUTOFMEMORY<br />

is defined as 0x80000002, <strong>and</strong> it can be passed to<br />

the function either as 0x80000002 or as ­2147483646.<br />

Values between 2147483648 (0x80000000) <strong>and</strong><br />

4294967295 (0xFFFFFFFF) automatically get<br />

converted into negative number values.<br />

cParam1<br />

Optional. When the message text contains a<br />

wildcard “[1]” <strong>and</strong> a string is given for cParam1, the<br />

function replaces the wildcard with the string.<br />

cParam2<br />

Optional. When the message text contains a<br />

wildcard “[2]” <strong>and</strong> a string is given for cParam2, the<br />

function replaces the wildcard with the string.<br />

cParam3<br />

Optional. When the message text contains a<br />

wildcard “[3]” <strong>and</strong> a string is given for cParam3, the<br />

function replaces the wildcard with the string.<br />

Comments<br />

In case the operating system supports several<br />

language versions, the function will search for the<br />

message text in the following sequence:<br />

1. Current Visual FoxPro localization<br />

2. Language­neutral<br />

3. Language setting of the threads<br />

4. Default language setting of the user<br />

5. Default language setting of the system<br />

6. English (USA)<br />

In addition to this, if the system itself supplies<br />

no message text, the function tries to load the<br />

following file <strong>and</strong> to retrieve the message text in it:<br />

Module<br />

Error<br />

numbers<br />

Declaration Comments<br />

wininet.dll From 12000 wininet.h Microsoft<br />

to 12999<br />

Win32<br />

Internet API<br />

If the message text concludes with one or<br />

several of the characters CR, LF, TAB, or SPACE,<br />

the function automatically chops them off.<br />

With an OLE error you can determine the<br />

COM/OLE error number via AERROR() <strong>and</strong> pass<br />

it to this function as nErrorCode, e.g. 0x080020005<br />

for a type conflict.<br />

Page 8 FoxRockX May 2011


Most Windows API<br />

functions do not return error<br />

numbers directly. Instead they<br />

retrun a value defined as invalid,<br />

like NULL, FALSE, or ­1. Only<br />

calling the Windows API<br />

function GetLastError() yields<br />

the actual error number. You<br />

will find further information<br />

in the documentation of the<br />

respective Windows API<br />

functions.<br />

The FoxPro comm<strong>and</strong><br />

ERROR as a clause does not<br />

only permit numerical FoxPro<br />

error numbers, but also<br />

strings. Here you can directly<br />

use the return value from<br />

GetWinErrorString(). For instance, the comm<strong>and</strong><br />

ERROR GetWinErrorString(1223)<br />

will raise the FoxPro error 1098 with the<br />

message text (that is localized according to the<br />

operating system) “Process aborted by the user“.<br />

Examples<br />

Here we attempt to create a folder with an invalid<br />

path name. When an error occurs, CreateDirectory()<br />

returns 0, <strong>and</strong> the subsequent call of GetLastError()<br />

yields the Win32 error number. By means of<br />

GetWinErrorString() we convert that error number<br />

into a string which we then report to FoxPro via<br />

ERROR:<br />

SET LIBRARY TO dfpug.<strong>fll</strong><br />

DECLARE Integer CreateDirectory ;<br />

IN WIN32API ;<br />

String lpPathName, ;<br />

Integer lpSecurityAttributes<br />

DECLARE Integer GetLastError ;<br />

IN WIN32API<br />

IF 0 = CreateDirectory(“Test:\/”,0)<br />

ERROR GetWinErrorString(GetLastError())<br />

ENDIF<br />

The following example demonstrates<br />

the behaviour of the<br />

function when the message text<br />

contains wildcards:<br />

SET LIBRARY TO dfpug.<strong>fll</strong><br />

#define ERROR_WRONG_DISK 34<br />

? GetWinErrorString(;<br />

ERROR_WRONG_DISK)<br />

? GetWinErrorString(;<br />

ERROR_WRONG_DISK,”A:”,,;<br />

”0000-0000”)<br />

? GetWinErrorString(;<br />

ERROR_WRONG_DISK,”A:”,;<br />

Disk 1”,”0000-0000”)<br />

Figure 5. <strong>–</strong> Example about the Windows System Info<br />

GetShortPath<br />

Converts a long path name or file name into its<br />

short equivalent (MS­DOS 8.3 convention).<br />

GetShortPath( cFileName | cPath )<br />

Return value<br />

Character.<br />

Parameter<br />

cFileName, cPath<br />

Character. Absolute oder relative path name or file<br />

name. The folder or file must exist.<br />

Comments<br />

If the given path name or file name already fulfills<br />

the MS­DOS 8.3 convention, the function returns<br />

the path name or file name unchanged.<br />

In case the drive supports no 8.3 file names <strong>and</strong><br />

the path length exceeds 67 characters, the function<br />

will produce the FoxPro error 1098 with an appropriate<br />

message text such as “Wrong Parameter.”<br />

Example<br />

SET LIBRARY TO dfpug.<strong>fll</strong><br />

?getshortpath(“C:\Programme”) && C:\PROGRA~1<br />

Figure 6. <strong>–</strong> Example of an entry in the Windows Event Log<br />

May 2011 FoxRockX Page 9


RegisterEventSource<br />

Adds those items to the Windows Registry which<br />

are necessary so that the Event Viewer can convert<br />

event numbers into a suitable message text.<br />

Note: Generally you need administrator rights to<br />

be able to execute the function successfully.<br />

RegisterEventSource( [ cSourceName ] [,nTypes-<br />

Supported] )<br />

Return value<br />

Numeric.<br />

If it has been executed successfully, the function<br />

returns 0 (ERROR_SUCCESS).<br />

If an error has occurred, the function returns a<br />

Win32 error code which you can convert into a<br />

message text through GetWinErrorString().<br />

ReportEvent<br />

Adds an entry to the Windows application log.<br />

Note: The concept “ReportEvent” means “report<br />

an event” <strong>and</strong> has nothing to do with the concepts<br />

“Report” or “Event” as they are used in FoxPro!<br />

The name of this function was deliberately chosen<br />

because (a) the underlying Windows API function<br />

also bears the name ReportEvent(), <strong>and</strong> (b) because<br />

presumably in many projects there are already<br />

functions or methods with the name “Log”, <strong>and</strong><br />

therefore conflicts or mix­ups would be quite likely<br />

if similar names were used.<br />

ReportEvent( [cUNCServerName] , [cSourceName]<br />

, [nType] , nErrorCode [ , [cParamCode] [<br />

,cRawData]] )<br />

Return value<br />

Numeric.<br />

If it has been executed successfully, the function returns<br />

0 (ERROR_SUCCESS).<br />

If an error has occurred, the function returns a<br />

Win32 error code which you can convert into a<br />

message text through GetWinErrorString().<br />

Figure 7. <strong>–</strong> Converting URLs into Escape sequences<br />

UrlEscape<br />

Converts characters which are not allowed in URLs<br />

into the respective Escape sequences (“%xy”).<br />

UrlEscape( cURL [,nFlags] )<br />

UrlUnescape<br />

UrlUnescape<br />

Converts Escape sequences (“%xy”) in a URL into<br />

readable text.<br />

UrlUnescape( cURL [,nFlags] )<br />

IsWinNT<br />

Tells whether the operating system is based on<br />

Windows NT (WinNT, 2000, XP, 2003, Vista).<br />

IsWinNT()<br />

Return value<br />

Logical.<br />

Comments<br />

On Windows 9x systems (Win95, 98, ME) , the function<br />

always returns .F.<br />

Alternatively to this function you may also use<br />

the FoxPro function OS(6) to query the OS platform.<br />

The return value “2” (Caution: String!) indicates<br />

that it is a Windows NT­based operating system.<br />

UserName<br />

Returns the name of the user or of the security policy<br />

by which the current thread is being executed.<br />

This need not necessarily be the name of<br />

the currently logged­in user. On Windows NTbased<br />

operating systems (WinNT, 2000, XP, 2003,<br />

Vista) you can run programs under different login<br />

credentials (“Execute as...”).<br />

UserName( [nFormat] )<br />

Return value<br />

Character.<br />

Parameters<br />

When you call the function<br />

without any parameter, it<br />

returns the user name under<br />

which the current thread is<br />

being executed.<br />

nFormat<br />

In Windows 2000, by providing<br />

the optional parameter<br />

nFormat you can determine the<br />

user name of the name or the<br />

security principal in various<br />

formats.<br />

The function returns an<br />

empty string if the user name<br />

cannot be determined in the<br />

given format, or if the domain controller is not<br />

available for a request, or the value for nFormat is<br />

invalid.<br />

Page 10 FoxRockX May 2011


Figure 8. <strong>–</strong> display of the user name<br />

Comments<br />

System requirements: The optional parameter<br />

nFormat is only supported on Windows NT­based<br />

operating systems from Windows 2000 onwards.<br />

On all other operating systems (Win95, 98, ME,<br />

NT4) the function triggers the FoxPro error 1098<br />

with a matching message text, e.g. “This function is<br />

not supported by the system.”<br />

The calling of this function without the optional<br />

parameter nFormat is supported by all operating<br />

systems Visual FoxPro can run on.<br />

You can apply either IsWinNT() or the FoxPro<br />

function OS(6) to query the OS platform. A return<br />

value of “2” (Caution: String!) means that it is a<br />

Windows NT­based operating system.<br />

You may use the FoxPro function OS(3) to retrieve<br />

the main version number of the operating<br />

system. E.g. in Windows 2000, OS(3) yields the<br />

String “5”.<br />

At a single workplace PC<br />

without a domain membership<br />

<strong>and</strong> without an Active<br />

Directory, generally only<br />

function calls with nFormat = 2<br />

or without nFormat will return<br />

a sensible value.<br />

A security principal is an<br />

account owner to whom a security<br />

ID for the access to resources is<br />

being assigned automatically. A<br />

security principal can be a user, a<br />

group, a service or a computer.<br />

Defined names are strings<br />

according to the RFC 1779.<br />

nFormat Description Example<br />

N/A User name. JohnDoe<br />

1 Fully qualified defined name.<br />

CN=John Doe, OU=Software,<br />

OU=Engineering, O=Widget, C=US<br />

2 Windows NT 4.0 compatible SAM account<br />

name.<br />

Engineering\JohnDoe<br />

3 Complete name. As a rule, this name consists<br />

of the first name <strong>and</strong> the surname. It does not<br />

necessarily have to match the value CN of the<br />

fully qualified defined name.<br />

JohnDoe<br />

6 GUID {4fa050f0-f561-11cf-bdd9-00aa003a77b6}<br />

7 Canonical name engineering.widget.com/software/John Doe<br />

8 User Principal Name (aka UPN). johndoe@engineering.com<br />

9 Same as canoni-cal name (nFor-mat=7) except<br />

that the first slash from the right is replaced by<br />

a line feed character.<br />

engineering.widget.com/software<br />

John Doe<br />

10 Generalized ser-vice principal name. www/srv.engineering.com/engineering.com<br />

12 DNS domain name followed by a backslash ("\") engineering.widget.com\JohnDoe<br />

<strong>and</strong> the SAM user name.<br />

Memberware<br />

FoxRockX subscribers can download the <strong>dFPUG</strong>.<strong>fll</strong><br />

<strong>and</strong> the sample application described from http://<br />

portaladmin.dfpug.de/ dokumente/foxtalk/memberware/.<br />

FoxRockX subscribers may use the <strong>dFPUG</strong>.<br />

<strong>fll</strong> in their own applications <strong>and</strong> also h<strong>and</strong> it over<br />

to their customers. The code from the samples, <strong>and</strong><br />

the wrapper class for the encapsulation of the ZIP<br />

functionality <strong>and</strong> provision of the progress bar may<br />

also be integrated into own applications <strong>and</strong> may<br />

thus be h<strong>and</strong>ed over to customers.<br />

The license of the memberware is valid as long<br />

as the FoxRockX subscription exists. The license expires<br />

at the end of the subscription.<br />

Have fun using the <strong>dFPUG</strong>.<strong>fll</strong>!<br />

May 2011 FoxRockX Page 11

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!