SQLExpress - Xb2.NET
ot4xb
Search
Start
>
Forums
>
xfree.resources (readonly)
>
Phil Ide Packages
xfree.resources (readonly)
Phil Ide Packages
Thread Starter:
Pablo Botella
Started:
5/7/2008 1:45 PM UTC
Replies:
19
5/7/2008 1:45 PM UTC
Phil Ide Packages
Pablo Botella
Hello,
In this thread you can found the packages rescued from the web site of Phil Ide
As this site is readonly, to add a package you can use the following NG
news://news.xb2.net/xfree.tmp_unedited
and reply to the corresponding thread with the package attaches as a ZIP file.
Thanks,
Pablo Botella
------------------------------------------------------------------------
Hola,
En este hilo podeis encontrar los paquetes que se han podido rescatar de la web de Phil Ide
Como este sitio es READONLY, para añadir un paquete podeis usar el siguiente NG
news://news.xb2.net/xfree.tmp_unedited
y responder al hilo correspondiente adjuntando el packete como fichero ZIP
Gracias,
Pablo Botella
------------------------------------------------------------------------
Hello guys
In this area, we want to post all Phil Ide source' code that we found it.
So, please if some want to share, send it to me and I will upload ASAP.
Thanks Phil
Best Regards
Osvaldo Ramirez
------------------------------------------------------------------------
5/7/2008 1:46 PM UTC
XML
Pablo Botella
5/7/2008 1:49 PM UTC
XML [ Modified by Javier (Syga System) ]
Pablo Botella
This code is based on the XML work from Phil, this class was changed by Javier from Syga System, S.L and try to use XSD files and convert it to XML
HTH
Osvaldo Ramirez
-------------------------------------------------
Codigo para usar XML y mejorado por nuestro amigo Javier de Syga System, S.L. el cual permite usar Documentos XSD y convertirlos en XML
Espero que les sirva
Osvaldo Ramirez
This message includes the following attachments:
xmlzio.zip
5/7/2008 3:38 PM UTC
XbFPT
Pablo Botella
Rescued by: Hector Pezoa, Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
--------------------------------------------------------------------
Author: Phil Ide
Special thanks to:
Mike Grace for finding most of the bugs
John Caswell for finding another bug
John Caswell for supplying the sendCommand method to send
arbitrary commands to the server.
--------------------------------------------------------------------
This message includes the following attachments:
xbftp.zip
5/7/2008 3:49 PM UTC
XbSSL - SSL Wrapper for OpenSSL and ASINET
Pablo Botella
Rescued by: Hector Pezoa
--------------------------------------------------------------------
Author : Phil Ide
Created: 07/04/2004
--------------------------------------------------------------------
XbSSL - SSL Wrapper for OpenSSL and ASINET
Introduction
This library will provide SSL capability to Alaska's ASINET internet protocols communications library. Provisionally it will concern itself with HTTPS, and at some later stage will provide SSL capability to FTPS, SMTPS etc.
It uses the OpenSSL libraries to achieve this. If you do no already have these, you should read the next section.
Installing OpenSSL
You need to get the Win32 OpenSSL binaries. Once you have them, run the installation package and select the default installation options. Once installed, you can (perversely) uninstall them. The uninstallation leaves the required DLL's in your %windows%\system32 directory, but removes the source code (which you probably don't want). The two DLL's are called libeay32.dll and ssleay32.dll. You can copy these to an application directory if you wish, or bundle them with your application.
Caveats
At this stage, the XbSSL() class is experimental. Each release will certainly work under at least one or more circumstances, but only testing will prove whether it will work under all circumstances. Additionally, since it is experimental, the exposed methods may change to incorporate a more generic or easier to use interface. Further, it is likely that a base class will be created in the future, with child classes to cater specifically for each of the various protocols.
Update History
v0.1
Basic connection to HTTPS servers. By default uses v3 contexts for clients.
This will change in th future to use Does not properly implement SERVER contexts --------------------------------------------------------------------
This message includes the following attachments:
xbssl.zip
5/7/2008 4:08 PM UTC
ABS182
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Author : Phil Ide
Created: 09-Feb-2005
--------------------------------------------------------------------
Xbase++ 1.90 changes the architecture of the class system in a subtle
but important way.
The ACCESS ASSIGN METHOD NoIvarCallback is no longer supported. In
future projects, you should use getNoIvar(), setNoIvar(). However, to
minimise the amount of changes you have to make to your source code so
it compiles (and runs properly) with 1.90, follow the instructions
below.
NOTE: This is ONLY necessary if you have implemented the NoIvarCallback
in your classes.
To include this class, simply add it to your projects, and when you
declare a class definition, make this class part of the inheritance
chain. This is best achieved at the most senior level of class.
For example:
CLASS myClass FROM AbstractCompatibility182
...
ENDCLASS
Now myClass and any class that inherits from it will be compatible
with Xbase++ 1.82's architecture.
--------------------------------------------------------------------
This message includes the following attachments:
abs182.zip
5/7/2008 4:12 PM UTC
AJAX
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Author : Phil Ide
Created: 18-Jun-2005
--------------------------------------------------------------------
Using AJAX with WAA and javascript
This message includes the following attachments:
ajaxsrc.zip
5/7/2008 9:15 PM UTC
Smart Object
Pablo Botella
Rescued by: Hector Pezoa, Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Versions: 2005.09.05 and 2003.12.18
--------------------------------------------------------------------
Author: Phil Ide
--------------------------------------------------------------------
Current version: 1.4
SmartObjects is a term I coined to describe classes of objects that utilise the inbuilt
error handling of the class system in XBase++ to do two things:
1. Require the object to interpose between the program and the data
for both inbound (assign) and outbound (read) access.
2. To protect the raw data from the program whilst still providing a
property (iVar) interface.
There are probably lots of ways where this could prove useful, but as an example
(and remember, this is not the only use) I have created a series of classes which
emulate C/C++ structures. For other examples, checkout:
GPContainer() is a general purpose container class for arbitrary
collections of data. It is compatible with all versions of Xbase++.
GPContainerPGSql() builds on the properties and features of
GPContainer(), to provide automatic creation of SQL statements and
firing them at the PostgreSQL server.
Now, back to SmartObjects...
Note that these classes are not complete (I'll leave that as an excercise for you),
and therefore do not handle the following:
a) Unions
This could be implemented, but as yet I don't have the need and
I have too many other projects demanding my attention.
b) Members by reference
You cannot create individual members as pointers.
c) Callbacks
This is another facet of 'Members by reference'.
So what does the Structure() classes give?
1. Strict typing at runtime. Create a ULONG and it must be both numeric and positive, and it's value must fit in 32 bits. Assign any other value, and you'll get an error.
2. The ability to emulate many WinAPI structures, or create your own. With the
exceptions that the classes cannot handle (see above), there is only one other
caveat:
Occassionaly, a C/C++ compiler will extend a structure to a boundary. When
passing a structure to a WinAPI function, the structure must be of the expected size. The classes here cannot determine under what conditions
this resizing occurs, and therefore the structures are predetermined by the
accumulated size of the members.
Other than this occassional problem, creating structures and using them seems
to work fine.
In addition, the Structure() classes contain a .cargo slot. This member variable
does not form part of any structure, but is always available for storing
arbitrary information.
There is also a sizeOf() method, which can be used to determine the
current size of the structure. Some structures contain a variable
length member at the end of the member list, and if so the size of the
structure is affected by the current length of this member, otherwise
sizeOf() will return a constant value for each structure definition.
e.g.: myStruct.sizeOf() -> nSize
To create a structure, you use this syntax:
STRUCTURE <structName>
<type> <membername> [SIZE <nSize>]
[<type> <membername> [SIZE <nSize>]]
[STRUCT <membername> AS <structureName>]
ENDSTRUCT
The supplied example classes offer member types of:
WORD
DWORD
HANDLE
INT
UINT
SHORT
USHORT
LONG
ULONG
CHAR
The test project creates an executable called SOTEST.EXE. Running this will cause a
few lines of output followed by a runtime error. You should run the application
through a debugger to find out what is going on. The first time, simply F10 to step
through each statement in the test program, then if you are interested, try F8 to step into the classes themselves and see why they behave the way they do.
Remember, the classes supplied here and the test program are only to show you how
things can be made to work. SmartObjects is a philosophy, not a set of classes.
If you find any other interesting uses for SmartObjects, please let me know.
Any examples supplied could also find themselves in this package, so please feel
free to show me what you've done.
Regards
-- Phil Ide.
This message includes the following attachments:
smartobjects_2005_09_05.zip
smartobjects_2003_12_18.zip
5/7/2008 9:20 PM UTC
Gradient
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Author : Phil Ide
Created: 09-Apr-2003
--------------------------------------------------------------------
CLASS TriGradientForm FROM GradientForm
EXPORTED:
METHOD init
METHOD create
METHOD buildVertex
ENDCLASS
--------------------------------------------------------------------
CLASS GradientForm FROM XbpDialog
EXPORTED:
VAR aColor
VAR gRect
VAR gradientDirection
VAR vertex
VAR bVertex
METHOD init
METHOD create
METHOD subpaint
METHOD TriVertEx
METHOD setColor
METHOD buildVertex
ENDCLASS
--------------------------------------------------------------------
Function Dialog1( aMetric, nWidth, nHeight )
local aPos[2]
local oDlg
aPos[1] := (aMetric[1] - (nWidth/2)) - 20
aPos[2] := aMetric[2] + 20
oDlg := GradientForm():new(,,aPos,{nWidth,nHeight})
oDlg:title := "[Rectangle] graduate from left to right"
oDlg:sysmenu := TRUE
oDlg:tasklist := TRUE
oDlg:setColor(1,14,23,92)
oDlg:setColor(2,198,205,254)
oDlg:create()
return oDlg
This message includes the following attachments:
gradient.zip
5/7/2008 9:36 PM UTC
capwin
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Author : Phil Ide
Created: 17-Oct-2003
--------------------------------------------------------------------
There are three functions:
CaptureWindow(hWnd) -> oXbpBitMap
returns a bitmap object of the selected window
hWnd can either be the handle of the window (oDlg:getHWnd()), or
you can just pass the window object in and the function will resolve
the handle itself.
CaptureWin2File( oDlg, cFile, nImgType ) -> lSuccess
return TRUE if the file was successfully saved.
oDlg is either a window object or a window handle.
cFile is the name of a file to save to. This is optional, and
the default will be 'ScreenDump'. The file extension is dependant
upon the image format requested.
nImgType is one of the image types supported by Xbase++. Use one
of the XBPBMP_FORMAT_* constants.
If the file extension is specified, it will be used regardless of
whether it matches the requested format.
If the file already exists, it will be overwritten.
PrintWindow( hWnd ) -> NIL
hWnd
must
be a valid window handle. This is a C function which captures
the selected window as a bitmap and copies it to the clipboard.
To use this function, you must include this line in your source:
#include "printWin.ch"
Note that you can pass controls instead of windows. The example code shows
firstly a capture of a window, then the capture of a pushbutton.
This message includes the following attachments:
capwin.zip
5/7/2008 9:39 PM UTC
FReader
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Author : Phil Ide
Created: 04-Jun-2005
--------------------------------------------------------------------
FileReader
Author : Phil Ide
Copyright Phil Ide 2004-2005, All Rights Reserved
Version 1.0
Basic API's implemented for:
Generic Dynamic Read
TBrowse
XbpBrowse
XbpQuickBrowse
Purpose:
Create a generic class for reading individual lines from an ASCII text
file, where lines (or records) are delimited by some token. Usually
the token would be a Carriage-Return/Line-Feed pair, but this is
configurable. The class attempts to minimise and optimise the loading of
data by caching unread lines and storing information about line offsets
and their length. The cache is nominally 4Kb in size, and will not
usually grow beyond 8Kb at most, although this is dependant upon the data
you are attempting to access.
The class opens a file for reading in shared mode, and will work in one
of two basics modes:
Mode #1 - Dynamic Access
------------------------
In this mode, the reader knows very little about the file except that it
has successfully opened it, and the records/lines are delimited by a
known token. As each line is requested, the class determines whether
it knows anything about that line (i.e. the starting offset within the
file, and the length of the line). If it knows about the line - i.e. it
has read the line before - then it can easily reload the data for that
line. If it does not know about the line, then it must load any lines
between the last line it knows about and the requested line. As it loads
each line, it accumulates knowledge about the file, aiding fast
navigation to parts of the file it already knows about.
Mode #2 - Examined Access
-------------------------
In this mode, the class must perform an examination of the file before it
can be properly used (this is achieved via the ::examine() method). This
build a list of line offsets from which it is possible to browse the data
based purely on line numbers. Once examined, the class can be used in
TBrowse, XbpBrowse and XbpQuickBrowse.
Basic Navigation:
-----------------
Navigation through the data is achieved through the ::skip(<n>) method,
where <n> is NIL or any positive or negative number. Like dbSkip(), it will
only advance/recede where there are lines of data to traverse, so if
the current line number is 2 and you ::skip(-5), the resulting current line
will be line #1. The same goes for attempts to skip past the end of file.
The current line number can usually be determined by the iVar ::curLine.
An alternative to ::skip(-1) is ::rewind(), which performs exactly the
same operation. Note that neither ::skip() nor ::rewind() actually read
data (except where ::skip() takes the file pointer beyond any data the class
has so far read). ::skip(0) does not do anything - it does not re-align the
data pointer, the file cursor or re-read the current line.
To fetch the data for the current line, use the method ::readLine().
Using this method automatically advances the ::curLine pointer to the
next line after the data has been read.
You can go to a specific line using ::goTo(<n>), but only if the file has
previously been ::examine()'d or the target line has already been read.
METHODS and IVARS
=================
Class Methods
-------------
:new(<cFile> [,<cEOLToken>]) -> oFileReader
Creates an instance of the FileReader() class.
<cFile> is the name of the file to access, and may include a full path.
<cEOLToken> is an option string defining the end-of-line token that
delimits lines/records. The default is a carriage-return/line-feed pair.
Configuration
-------------
:stripEOL
This logical value indicates whether the return value of :readLine()
should strip the end-of-line token from the result. The default is TRUE,
ensuring the end-of-line token is not returned.
:dataWidth
This numeric value is used in XbpQuickBrowse to determine the fixed-width
of the return value. The default is 72 (chars), and :readLine() will
right pad the the return value to this length.
Life Cycle
----------
:configure() -> self
Resets the object to the pristine state as is it had just been created
with FileReader():new(). This releases buffered data and and destroys
any knowledge about the current file. It will continue to use the same
file.
:close() -> self
As for :configure() but also closes the file handle.
Navigation Methods
------------------
:goBottom() -> self
Sets the last (known) line as the current line.
:goTo(<n>) -> lSuccess
Sets the current line pointer to line <n>. Returns TRUE if successful.
:goTop() -> self
Sets the first line as the current line.
:rewind() -> lSuccess
Decrements the current line pointer. Returns TRUE if successful.
:skip(<n>) -> nSkipped
Advances the current line pointer by <n> lines if positive, or
decrements the line pointer if negative. Returns the actual number of
lines it was possible to skip.
:goPosition(<n>) -> nCurrentLine
Sets the current line using a percentage - i.e. :goPosition(25) will
locate theline which is at the position 25% from the start of the file.
Note that this is only an approximation. Returns the actual line
number that is set as the current line.
Methods
-------
:eofPos() -> nEofPos
Returns the offset of the end-of-file - in other words, the file size.
:examine() -> self
Causes the object to build a list of information about the lines of
data in the file. This must be called before using any type of browse (
TBrowse, XbpBrowse, XbpQuickBrowse). Note that for XbpBrowse, the method
:configureXbpBrowse() automatically calls :examine().
Depending upon file size, this can be a time consuming processes.
Files of 12Mb will usually take around 2-3 seconds, depending upon CPU
speed, memory etc.
:lineNo() -> nCurLine
Returns the current line number.
:reexamine() -> lDataAdded
This causes the object to check the file to see if any new data has
been added to the file by another process/thread, and if there is new
data to perform a mini :examine() to add the information on te new data
to the object. The method returns TRUE is new data is available.
:readLine() -> cLine
Returns the current line of data. The pointer indicating the current
line is advanced by one.
:position() -> nPos
Returns the current line number as a percentage of the total number of
lines. You must have called :examine() for this method to return a
meaningful result.
:currentLine() -> cLine
Rereads the data for the current line without advancing the current
line pointer.
:fileName() -> cFile
Returns the full name (including path if supplied) of the file being
accessed.
:baseFileName() -> cFileName
Returns the file name of the file being accessed without any path
information.
XbpBrowse specific methods
--------------------------
:configureXbpBrowse( <oBrowse> ) -> self
Having initialised an XbpBrowse, call this method passing the
browse ojbect as a parameter, before the browse is :create()'d.
This method installs the correct skip blocks and performs an automatic
:examine() of the FileReader() object (this allows the scroll bars to
work correctly).
XbpQuickBrowse specific methods
-------------------------------
The following methods are used to emulate the DacPagedDataStore class, and
should not be used directly.
:getRowData()
:getRowInfo()
:bindView()
:setAbsolutePageSize()
:getPos()
:getRelativePageSize()
:scrollDown()
:scrollUp()
:isFirst()
:isLast()
:rowCount()
:getRowCount()
:goFirst()
:goLast()
:goPrev()
:goNext()
This message includes the following attachments:
freader.zip
5/7/2008 9:47 PM UTC
iniedit
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Author : Phil Ide
Created: 30-Jul-2003
--------------------------------------------------------------------
Application: IniEdit.exe
Author: Phil Ide
Copyright: Phil Ide 2003, All Rights Reserved
Additional Code:
Program: TINIFILE
Author: Matt Hamilton (Corrections to ':ReadString' by Terry Wolfe)
( Down loaded from TheOasis )
Copyright: Released to Public domain by Original Author Matt Hamilton
Corrections to ':ReadString' released to public domain
by Terry Wolfe of Service Education, Inc.
Date: 11/22/99
Purpose: A Class to handle the .INI files
==========================================================================
IniEdit is written chiefly as an example of how to make an XbpTreeView
co-operate with an MLE and an SLE (and the MLE co-operate with the SLE
and the XbpTreeView etc.).
For another example, please see Folder Browser, also available from my
site.
http://www.idep.org.uk/xbse/foldbrow.zip
You can simply run IniEdit, in which case it will prompt you for an
ini file to edit, else you can pass the filename on the command line.
If you use the command line option, then you must pass the extension.
By default, Windows expects ini files to be in the %windir% directory
unless you supply a full path. IniEdit however, always checks the
current directory, and only falls back on %windir% if the file is not
found.
If the file is not found (and if no path is supplied and it is not in
%windir%), then IniEdit will simply quit without notification.
You can use the treeview to browse the entire file. If you highlight
a section, then the entire section appears within the MLE.
You can navigate within a section using either the treeview or the MLE -
to use the MLE, simply click on a line containing a value.
To edit a value, click on the SLE, type the new value and press the
enter key. The ini file is updated immediately, and the MLE will reflect
the change immediately too.
To delete either a key or a section, highlight it in the treeview and
right-click to bring up a context menu.
The 'Cancel' button will restore the original file and then quit the
application.
Regards,
--
Phil Ide
http://www.idep.org.uk/xbase
This message includes the following attachments:
iniedit.zip
5/7/2008 9:50 PM UTC
INI Files
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Program: TINIFILE
Author: Matt Hamilton (Corrections to ':ReadString' by Terry Wolfe)
( Down loaded from TheOasis )
Copyright: Released to Public domain by Original Author Matt Hamilton
Corrections to ':ReadString' released to public domain
by Terry Wolfe of Service Education, Inc.
Date: 11/22/99
Purpose: A Class to handle the .INI files
--------------------------------------------------------------------
TIniFile for XBase++ by Mab (Matt Hamilton)
==============================================
This is a direct port of the TIniFile class from Borland Delphi.
It encapsulates the GetPrivateProfile* and WritePrivateProfile* functions
in the Windows API.
This is free! Use it at your own risk, but I'm fairly sure its safe!
Cheers,
Mab
mhamilton@bunge.com.au
----------------------------------------------
The methods included are:
init(AFilename)
Creates a new TIniFile with the given filename. If the full path is
not given, then the file is created/found in the windows directory.
Example: IniFile := TIniFile():New("win.ini")
ReadSections(AList)
Returns in AList an array of all the section names in the inifile.
AList must have already been initialised to {}.
Example: IniFile:ReadSections(SectionList)
ReadSection(ASection, AList)
Returns in AList an array of all the key names in the given section.
AList must have already been initialised to {}.
Example: IniFile:ReadSections("Desktop", KeyList)
ReadSectionValues(ASection, AList)
Returns in AList an array of all the key names and their values in
the given section.
Each element in the resulting list will have the form "key=value".
AList must have already been initialised to {}.
Example: IniFile:ReadSectionValues("Desktop", KeyList)
ReadString(ASection, AKey, ADefault)
Returns the string specified in AKey and ASection. If the key or
section are not found, returns ADefault. ADefault
must
be specified.
Example: LastUser := IniFile:ReadString("Options", "LastUser", "Mab")
ReadInteger(ASection, AKey, ADefault)
Returns the integer specified in AKey and ASection. If the key or
section are not found, returns ADefault. ADefault
must
be specified.
Example: Width := IniFile:ReadInteger("Options", "Width", 80)
ReadBool(ASection, AKey, ADefault)
Returns the logical value specified in AKey and ASection. If the key or
section are not found, returns ADefault. ADefault
must
be specified.
Example: IsNew := IniFile:ReadBool("Options", "New", .t.)
WriteString(ASection, AKey, AString)
WriteInteger(ASection, AKey, AnInteger)
WriteBool(ASection, AKey, ABool)
Writes the given data back to the ini file.
Example: IniFile:WriteString("Options", "LastUser", "Mab")
DeleteKey(ASection, AKey)
Removes the given key from the ini file.
Example: IniFile:DeleteKey("Options", "LastUser")
EraseSection(ASection)
Removes the given section from the ini file.
Example: IniFile:EraseSection("Options")
This message includes the following attachments:
Inifiles.zip
5/7/2008 9:54 PM UTC
IPC Signal
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Class : IPCSignal()
Description: Inter-Process Signal() class
Author : Phil Ide
--------------------------------------------------------------------
Within a process (application), you can use the Signal() class to
cause one thread to wait for another. Both threads have to have a
reference to a single instance of the Signal() class.
One thread issues an oSignal:wait(), which puts the thread to sleep
until it recieves a signal. The signal is issued by the other thread by
calling oSignal:signal().
If you have 3 threads, two can be placed into a sleep state, but when
the signal is issued, both sleeping threads come alive again.
The Signal() class can be used to synchronize two or more threads within
a single application, but you cannot 'queue' requests (i.e. the sleeping
threads come alive one at a time) and you cannot use the class to
synchronize two (or more) sperate applications.
The IPCSignal() class resolves these issues. When you create an instance
of this class, it attempts to create a MUTEX, and then it tries to
gain control over it. Only one thread across all applications can
gain control of a mutex.
When the controlling thread has finished with the mutex, it releases it,
and control is automatically passed to the next thread waiting to gain
control, no matter which application that thread is in.
This fine control of mutexes is available through the WinAPI.
Since it uses mutexes, there is no need to pass instances of the
IPCSignal() class either between threads or applications.
Synposis:
create object, define mutex name
The mutex name must be exactly the same in all applications
which wish to use this mutex.
oSignal := IPCSignal():new('MY_MUTEX')
create() gets handle to mutex
oSignal:create()
after create, we may actually already have control.
we can test this easily:
oSignal:isOwner()
wait() will put thread to sleep until control is gained
if we already have control, returns immediately
oSignal:wait()
when we have finished blocking other threads/applications
we need to pass control to next waiting thread
oSignal:signal()
You can pass a numeric parameter to the wait() method, which defines its
behaviour:
Value Meaning
----------------
-1 Attempt to gain control, return immediately
(use oSignal:isOwner() to see if you have control)
0 Wait forever until control is gained
0 Timeout period in seconds
use oSignal:isOwner() to see if you have control
test oSignal:lTimeOut to see if timeout occurred
Additional methods:
:name() returns name of MUTEX (or NIL if not defined)
:handle() returns handle of mutex (or 0 if not available)
This message includes the following attachments:
ipcsignal.zip
5/7/2008 9:59 PM UTC
JS Recruiter
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Application: JSR.EXE
Author : Phil Ide
(c) Copyright Phil Ide 2006
---------------------------
WARNING:
-------------------------------------------------------------
To compile and link the source code, you'll need a developer edition
of HRF2 (you cannot use the version of HRF2 that comes with xbHCL unless
you have also purchased a seperate licence for HRF2).
-------------------------------------------------------------
This is an example application using HRF2. It fetches all the
'recruiter' names and addresses from Jobserve (www.jobserve.com) in
the IT section. The recruiters are usually recruitment agencies, but
may also be a company (e.g. ABN AMRO).
There is a filter you can use to collect just recruiter info for Great
Britain, just Australia, or both.
Usage:
jsr // default = GB recruiters
jsr gb
explicitely gb recruiters
jsr au
just au recruiters
jsr gbau
both au and gb recruiters (mixed)
The program works by requesting a 'start' page - a start page is the
first page in each alphabetic category, i.e. the first page of
recruiters beginning with 'A', the first page of recruiters beginning
with 'B' etc. (the 'A' page also contains non-alpha recruiters, such
as @its, 100% group etc.).
It extracts the list of recruiter names from the page, plus the link
to the details page for each recruiter, which it then fetches and
extracts the address and contact details for the recruiter.
Once it has extracted all the details for all the recruiters on the
page, it then checks to see if there are any additional pages in this
category by looking for hyperlinks at the bottom of the page to
subsequent pages, and repeats the process for each of those.
Details are recorded in a file named 'recruiter_x.dbx', where x is 'gb',
'au' or 'gb_au' depending upon which data it has been asked to fetch.
This is a plain text file, with records delimited by CRLF+'=='+CRLF.
Fields for the record are named with a colon following the name and
the data immediately afterward and the field terminated by CRLF. The
exception to this are the Address: fields, which have the data
starting on the next line.
Example:
Access Computer Consulting Plc
JS-ID=18258
Contact: Ed Turvey
Phone: 01256 368800 Fax: 01256 368811
Email:
info@accessplc.com
Address:
25-29 Church Street
Basingstoke
Hampshire
RG21 7QQ
England
==
Note that the recruiter name has no 'Name: ' tag. The JS-ID is the
Jobserve unique id for this recruiter.
This format allows some data to be missing (e.g. some recruiters have no
address or contact details), whilst still allowing the records to be
extracted programmatically using Xbase++ or Perl.
Using a 2Mb broadband connection, it took 10 minutes to fetch all the GB
details, and 1 minute 22 secs to fetch all the AU data.
You'll note the DOM addresses used in the code to fetch various nodes
from the currently downloaded page. These addresses were determined by
examining the page in httpAnalyze.exe, which is also written using
HRF2 and allows you to view the page source in a treeview.
At the time this code was written, these DOM addresses returned the
required nodes (html elements) from the page, but Jobserve may change
the layout or structure of the page at any time in the future, in
which case the DOM addresses will probably change.
This message includes the following attachments:
jsr.zip
5/7/2008 10:15 PM UTC
Load From URL
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Function: LoadFromUrl.prg
Author : Phil Ide
Copyright Phil Ide 2004-2005, All Rights Reserved
Version 1.15
Fix to LoadFromUrlObject() not passing through the bFtpCallBack
code-block.
Version 1.14
Allows news:// url's to be called. Requires ASINET or Xb2.NET to
access news url's, but can be compiled without either.
WARNING: lfromurl.ch has been updated!
Version 1.13
Allowed callback in HTTP/HTTPS to allow progress display and to allow
these types of transfers to be aborted.
Partial implementation of gopher protocol - doesn't seem to want to
work, so don't use it - however, if you can see what is wrong, please
let me know! There are two different attempts within the source:
GetGopherFileAAA() - uses WinInet Gopher...() routines
GetGopherFile() - uses InternetOpenUrl() for direct access
Version 1.12
Allowed FTP callback to be called even when the remote filesize
cannot be determined.
Version 1.11
Fixed BasicAuth authentication - no longer requires the base64
encoding routine, so bit-twiddle.lib has been removed.
Now supports FTP addresses as well. Please see explanation of
parameters for feedback/progress callback.
Version 1.10
Made a proper fix for chunked transfers
Version 1.9
Added 13th parameter (aSendHeaders) which must be passed by
reference. This allows the request HTTP headers to be returned. The
class has been updated to reflect this. Note that request headers
automatically include any suitable cookies.
Added half-second delay between fetching headers and fetching message
body when the headers indicate a chunked transfer. This isn't
foolproof, as the delay may in some cases need to be longer, but in
most cases this is sufficient to allow the chunks to arrive.
This can easily be resolved in W2K3 and XP/SP1 machines by
switching the WinHTTPAPI interface (instead of the HttpAPI
interface), which automatically handles chunked transfer encoding.
However, since that itsn't available on W2K, and Win9x machines, that
causes a problem. I might encode some optimisation branching to
switch between interfaces based on the current OS.
Version: 1.8
Added LoadFromUrlStatus() function.
This can be called after LoadFromUrl() to get the result status of
the query.
Added LoadFromUrlObject() class. This makes it easier to handle
the huge number of parameters. Some of the new parameters are
proving very useful and interesting, and making sure the correct
number of parameters are skipped can be error prone.
This class always fetches the http headers and the result status,
so it is not necessary to pass all parameters. The object created
has iVars with the same name as each of the parameters to
LoadFromUrl(), so if you want to set the method you can do this:
o := LoadFromUrlObject():new(cUrl)
all params can be passed here
// the same as in LoadFromUrl()
o:cMethod := 'POST'
o:cPostString := 'NAME1=Fred&NAME2=Ginger'
fire query
o:exec()
o:status() // 200=ok, 404=Not Found etc.
AEval( o:aHeaders, {|e| QOUT( e ) } )
print headers
cData := o:cResource // get data
Version: 1.7
fix for https requests
This version of LoadFromUrl() is 100% compatible with the function of the
same name in Alaska's ASINET library, plus it has some extended
functionality. Importantly, ASINET is NOT required to either use it or
recompile it. It is written in pure Xbase++.
In order to use the function, you will also need a copy of XbPCRE, the
Perl Compatible Regular Expression Library and Xbase++ wrappers. This is
available from my site at
http://www.idep.org.uk/xbase
.
There are 8 basic extensions to the original LoadFromUrl(), which are
identified by the 7 additional parameters detailed below. In addition to
this, there is an external interface to pre-configure additional HTTP
headers.
LoadFromUrl( cURL , ;
[nPortNumber] , ;
[nProtocol] , ;
[cProxyUrl] , ;
[acByPass] , ;
[cMethod] , ;
[cPostString] , ;
[cHttpHeaders], ;
[bPreCall] , ;
[lHeadersOnly], ;
[@aHeaders] , ;
[aAuthInfo] , ;
[@aSendHeaders],;
[bFTPCallBack])
cUrl
This is the URL (or URI) of the resource you wish to download. It should
be in the form:
[http[s]://]server[:port][/path_to_resource]
Note that the URL will take highest priority when setting protocol and
port options, overriding other parameters.
nPortNumber
This is the port number that the server is listening on for requests. If
it is specified in the URL, the port in the URL takes precedence.
You can use a constant to specify this value:
INTERNET_DEFAULT_HTTP_PORT - for HTTP protocol
INTERNET_DEFAULT_HTTPS_PORT - for HTTPS protocol (secure socket layer)
If omitted, this parameter defaults to the default port for the specified
protocol.
nProtocol
You can specify the protocol to use - note that this setting is
deprecated if a protocol is specified in the URL.
INTERNET_COMMUNICATION_PUBLIC selects HTTP protocol
INTERNET_COMMUNICATION_SECURE selects HTTPS protocol
If this parameter is missing, and the protocol is not specified in the
URL, the protocol will default to INTERNET_COMMUNICATION_PUBLIC.
cProxyUrl
This is the address (name or IP address) of a server to use as a
proxy. This takes the same format as the URL, but without a final
path_to_resource component.
You can specify more than one proxy to handle different protocols. To do
this, use the form:
protocol=url [protocol=url]
Example:
http=
http://mydomain.htproxy
https=
https://mydomain.hsproxy
If you do not supply this parameter, the function will determine and
use the system proxy settings (if any).
acByPass
This is used in conjunction with cProxyUrl, and specifies addresses which
should bypass the proxy - in other words, if a URL is matched against one
of the acByPass addresses, the proxy will not be used. This is useful
when targetting local network resources.
acBypass is an array of addresses either in name or IP address format.
cMethod
By default, the function will use the GET method to transmit data to
the server. You can set this value to 'POST', useful for submitting form
data. When set to POST, cPostString is mandatory.
cPostString
This is a CGI encoded string, usually form data, which you want
transmitted to the server along with the request URL.
cHttpHeaders
You can pass additional HTTP headers, which will be sent with the request
to the server. HTTP headers precede any POST data. You can use this to
specify language preferences etc.
You can specify more than one header, by seperating each header with a
carriage-return/line-feed pair.
bPreCall
This parameter is a code block which acts as a call-back. After
setting up the internet connection and preparing a path to the host
server, but prior to sending the request data, this code-block gets
evaluated. It is passed a handle to the specific internet connection
negotiating with the host server.
The purpose of this is chiefly so you can call AddRequestHeadersA() (see
below). This is more powerful and flexible than using cHttpHeaders,
but not as simple to use.
Example:
{|h| SetHeaders( h ) }
lHeadersOnly
When TRUE, this forces the function to only fetch the HTTP headers
for the resource. This doesn't request the resource, fetch the
headers then abort, it specifically requests only the headers for
the resource. To fetch the resource as well you must make a second
call to LoadFromUrl() with lHeadersOnly to false. The default for
this parameter is FALSE. Note that the return type changes if this
is TRUE.
aHeaders
This parameter must be passed by reference. If passed, it will be
populated with an array containing the HTTP headers for the resource.
This can be used to fetch the HTTP headers AND the resource in a
single call (lHeadersOnly must be FALSE). The function is
optimised to NOT fetch the headers if this parameter is not passed.
aAuthInfo
When used, this parameter supplies the Basic Authentic credentials for a
URI which is in a protected realm and using AuthBasic authentication.
The first element is the username, and the second element is the
password. Note that these are passed to the server in plain text.
aSendHeaders
When passed by reference, this is filled with an array of the HTTP
headers sent with the request.
By collecting and examining both the send and receive headers, it
is usually possible to identify errors.
bFTPCallBack
You can use this parameter to install a callback to monitor
progress of the download. This should be a code-block which
accepts two parameters. The first parameter is the total size of the
file being downloaded, and the second is the total number of bytes
downloaded so far.
If LoadFromUrl() is unable to determine the file size from the
server, then the first parameter passed to the callback will be zero.
The code-block should return a logical value indicating whether the
transfer should continue.
TRUE - continue download
FALSE - abort download immediately
If the download is aborted by the callback, then any data already
downloaded is returned.
(note: since v1.13 this callback is used by HTTP/HTTPS requests as
well as FTP)
RETURNS:
LoadFromUrl() returns either the resource requested (as a string) or
NIL on failure. If lHeadersOnly is TRUE and the function succeeds,
the return value is an array of HTTP headers for the resource. There
is one array element for each header, which is returned as a simple
string. If you wish to seperate the header token from it's value,
you must perform that operation yourself.
Additional Functions:
SetHttpDefaultHeaders()
AddRequestHeadersA()
Array2File()
vBase64()
SetHttpDefaultHeaders( cHeaders )
This function allows you to pre-set additional HTTP headers which are
then subsequently used whenever LoadFromUrl() is called.
You can either use this instead of the <cHttpHeaders> parameter of
LoadFromUrl(), or set default headers withthis function and context
specific headers with <cHttpHeaders>.
The headers should be formatted in the same way as <cHttpHeaders>. To
clear the headers from the cache (so they won't be used in the future),
call SetHttpDefaultHeaders() without any parameters (or explicitly pass
NIL).
AddRequestHeadersA( hConnect, lpszHeaders, dwHeadersLength, dwModifiers )
This is a WinAPI/WinInet function which can be used to selectively add,
delete, replace or merge HTTP headers. The semantics of the function are
set by the dwModifiers parameter.
hConnect
[in] Handle returned by bPreCall in LoadFromUrl()
lpszHeaders
[in] Pointer to a string variable containing the headers to append to
the request. Each header must be terminated by a CR/LF (carriage
return/line feed) pair.
dwHeadersLength
[in] Size of lpszHeaders, in TCHARs. If this parameter is -1L, the
function assumes that lpszHeaders is zero-terminated (ASCIIZ), and the
length is computed.
dwModifiers
[in] Controls the semantics of this function. This parameter can be a
combination of the following values.
HTTP_ADDREQ_FLAG_ADD
Adds the header if it does not exist. Used with
HTTP_ADDREQ_FLAG_REPLACE.
HTTP_ADDREQ_FLAG_ADD_IF_NEW
Adds the header only if it does not already exist; otherwise, an
error is returned.
HTTP_ADDREQ_FLAG_COALESCE
Coalesces headers of the same name.
HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
Coalesces headers of the same name. For example, adding "Accept:
text/*" followed by "Accept: audio/*" with this flag results in the
formation of the single header "Accept: text/*, audio/*". This
causes the first header found to be coalesced. It is up to the
calling application to ensure a cohesive scheme with respect to
coalesced/separate headers.
HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
Coalesces headers of the same name using a semicolon.
HTTP_ADDREQ_FLAG_REPLACE
Replaces or removes a header. If the header value is empty and the
header is found, it is removed. If not empty, the header value is
replaced.
Returns TRUE if successful
Array2File(cFile, a)
Takes a simple one-dimensional array (a) and writes it to a file
(cFile).
vBase64( cString )
Base64 encodes a string. There is no decode function available.
If you prefer, you can use Xb2.NET's xbBase64Encode() or Asinet's
toBase64() functions.
ADDITIONAL NOTES:
-----------------
LoadFromUrl() will masquerade as Internet Explorer 6 running on an XP
machine. Most web servers and web applications do not make demands about
which browser you use. However, a small number do, and unsurprisingly
they nearly all demand that you use IE. Therefore I've set the function
to pretend to be IE in the hope that it will absolutely minimise the chances
of a server rejecting it.
If a server DOES reject it BECAUSE it thinks it is IE, you can use
AddRequestHeadersA() to change the USER_AGENT string sent to the server, or
you can just modify LoadFromUrl() - the USER_AGENT string is set using a
#define very near the top of the source file.
For brave and adventurous people, there is a static function in the source
called ChopUrlIntoLittleBits(). You might find it useful in other
situations, in which case just remove the STATIC declaration to make it
globally visible.
This function accepts a URL and - well, it chops it into little bits. It
returns those bits in an array. You can use the following constants to
examine the array:
URL_PROTOCOL 'http','https','gopher','ftp','news' or NIL
URL_HOST server name or NIL
URL_PORT port number or NIL
URL_URI resource identifier (e.g. '/xbase/tencomm.html') or NIL
The values (or lack of!) are obviously dependant upon the information
contained within the URL.
The last five elements of the array are used by LoadFromUrl() as temporary
data storage and should be ignored.
Fetching NEWS Url's:
--------------------
Note that this isn't a full
implementation of the news:// url specification, since it doesn't
handle local url's. According to the specification, 'local' url's
take the form:
news://newsgroup/message
Note that the news-server host name has not been specified in the
url.
This implementation recognises and can handle 'remote' url's, that
is urls which contain the host address (which of course can be an
IP address or one of the local machine names).
Remote addresses take this form:
news://host/newsgroup
/message
If you need to refer to the current machine, you can use any of the
usual addresses/names, such as 127.0.0.1, 'localhost' etc.
The [message] can be a message-id without the enclosures:
For a message who's message-id header looks like this:
Message-ID: <
15h6c878vias2.dlg@idep.org.uk
>
Use:
15h6c878vias2.dlg@idep.org.uk
The [message] can also be a message number, but since message numbers
are specific to a particular server, you would first have to query
the server in order to retrieve the message number. However, this
URL is valid (even if it doesn't point to a message!)
news://news.alaska-software.com/alaska-software.news.3pp
/27
...and returns the 27th message in the 3pp newsgroup.
By default, LoadFromUrl.prg will compile without news:// capability. In
order to enable it, you require ASINET or Xb2.NET. At the top of the
source, you will see these definitions:
#define __ILIB_INOLIB__
No sockets library
//#define __ILIB_ASINET__
ASINET library
//#define __ILIB_XB2NET__
Xb2NET library
Comment out __ILIB_INOLIB__ and uncomment one of the other two as
appropriate to the library you wish to use.
This message includes the following attachments:
lfu1150.zip
5/7/2008 10:21 PM UTC
piCommon - general purpose command extensions
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
* Source : piCommon.ch
* System : general
* Author : Phil Ide * Created: 13/02/2002
* Purpose: general purpose command extensions
--------------------------------------------------------------------- DLLFUNCTION command enhanced
--------------------------------
superior type checking
these checks can be used in pre-processor statements even when the value
to be tested does not exist.
--------------------------------
This message includes the following attachments:
picommon.zip
5/7/2008 10:25 PM UTC
piWis - emulate some of the functionality of WIS
Pablo Botella
/*****************************
* Source : piWis.prg
* System : <unkown>
* Author : Phil Ide
* Created: 29/10/2003
*****************************/
This demonstrates how you can emulate some of the functionality
of WIS to download an updated file from the internet via http.
In this (real-life) example, the ABI codes (insurance groupings
for vehicles in the UK) is tested.
The web page with the link is downloaded and decomposed using HRF,
and the link to the file and the date it was last updated are extracted
and the date tested.
The date is tested against the file-creation date of the last version
downloaded, and if the web version is newer then it is downloaded and
saved to a unique filename.
I run this from a WAA application, in which I have installed a
scheduler thread, and is run once per day. The functionality for
calling this routine, extracting the data from the self-extracting
zip and importing into our own database is not supplied as part of this
sample since it is fairly much irrelevant.
If you want to test the routine, the url to use is:
http://www.abi.org.uk/carinsurance/download.asp
Note that whilst downloading web pages is pretty good, the downloading
of the data file is quite slow, even though it is very small. This is
because of their server setup, and is not an issue either with this code
or with ASINET or HRF.
Please note that you require ASINET and HRF to run this sample.
Additional Notes:
-----------------
Careful examination of the code will show some strange things.
For example, calling the following functions seems needless:
ExtractUrlFromAnchorInCell()
ExtractFileSizeFromCell()
ExtractFileDateFromCell()
You could for example, just do this:
aTables[1]:childList()[1]:href
...to get the url from the anchor. Also,
GetAllRootElementsByName( oTable, "tr" )
..may seem pointless too, because all the children of oTable are
in fact rows.
The first example simply makes the code more readable, and in fact
is simply easier to debug.
The second example ensures that spurious tags between rows are removed.
In the web page for downloading the ABI codes, this is not an issue, but
I have seen (and even used myself) <span> and <div> tags which are made
hidden/visible by JScript, and besides, the specification for HTML does not
preclude non-table tags being used between rows.
Note that GetAllRootElementsByName() may fail if there is text not enclosed
by tags - this is untested, and you should proceed with care. If you get an
error when examining a page, this is probably the point where the failure
will occur.
This message includes the following attachments:
piwis.zip
5/8/2008 11:08 AM UTC
Printer API
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
PrinterAPI
Program : <none, general>
Source : printerAPI.prg
Author : Phil Ide
Copyright: Phil Ide 2002-2003, All Rights Reserved
Additional Code
Source : Inifiles.prg
Author : Matt Hamilton, Terry Wolfe
Copyright: Released to Public domain by Original Author Matt Hamilton
Corrections to ':ReadString' released to public domain
by Terry Wolfe of Service Education, Inc.
Date : 11/22/99
Special Notes
The #define value BRENT_DUBS_MIN is named for Brent who discovered the following:
If Microsoft Word is not maximised when closed, subsequent calls to Word to print a document using the Windows ShellExecute "print" command will cause Word to briefly display either it's logo or it's document window, unless undocumented mode 12 is used.
Many thanks to Brent for finding this.
--------------------------------------------------------------------------------
Index
Purpose WinApiOpen() WinApiPrint() GetDefaultPrinter() SetDefaultPrinter() EnumPrinters() GetPrinterNameFromString() History 18th Sep 2003 28th Jly 2003 27th Jly 2003 25th Jly 2003 23rd Jly 2003 10th Feb 2003 Acknowledgements
--------------------------------------------------------------------------------
Purpose
These routines allow you to manipulate the default printer without being forced to get the user to assert changes for you. Usually, you would be forced to offer the user an XbpPrintDialog in order for them to select the printer to print on. In some circumstances though, you enough about their system to make that decision for them. In other cases, you might want to integrate the choice of printer with one of your own dialogs.
These routines offer you that flexibility, and even allow you to do such things as ask Windows to print a document for you, in which case Windows will print the document using the application which is registered with Windows as the default application for that file type.
For example, you might have a Rich Text Format (RTF) document which you have dynamically created, changed or selected. By asking Windows to print it for you, it will load WordPad, Word or Write (or whichever application is launched when you double-click on such a document), print the document and then unload that application. In this way you can avoid having to write the code which interprets RTF codes and outputs the properly formatted document to a printer.
In such cases, the printer used is always the default printer. If you wish to ensure that a specific printer is used and cannot gurantee that it is the default printer, these routines will enable you to:
Get the name of the current default printer Get the name of all printers installed on the system Set the default printer Notify automatically all currently running applications that the default printer has changed (requires that such applications are compliant with Windows specifications in this regard) Windows NT/W2K/XP use a different method for storing, registering and applying the default printer from Win9x/ME, and Win9x/ME also use a different method for notifying currently running applications that a change has been made. These routines automatically recognise whether the current application is running on an NT class machine or otherwise, and modify their behaviour accordingly to produce the correct results.
--------------------------------------------------------------------------------
WinApiOpen()
WinApiOpen( cFile, [cParms], [cDirectory], [nOpenMode] ) -> lOk
cFile is the name of the file you wish to edit/view
cParms is a comma seperated list (as a string) of any additional parameters you wish to pass to the called application
cDirectory is the name of the directory that should be used as the current directory by the called application
nOpenMode indicates the mode of the application (minimised etc.)
Various modes can be selected using the #define's in printerAPI.ch. You should use the default (see below).
Returns TRUE if successful
This function accepts a file name, and instructs Windows to open the file using the default application using file-type associations.
In most instances, the only parameter you need to pass is the name of the file you wish to open in edit/view mode. Unless you have a particular reason to use the other parameters, they are best left alone.
Examples: WinAPIOpen("default.html")
load the file into a web browser
WinAPIOpen("default.rtf") // load the file into a rich-text editor
WinAPIOpen("MyDialog.XFF")
edit a Dialog definition in Xbase++'s Form Designer!
WinApiPrint()
WinApiPrint( cFile, [cParms], [cDirectory], [nOpenMode] ) -> lOk
cFile is the name of the file you wish to print
cParms is a comma seperated list (as a string) of any additional parameters you wish to pass to the printing application
cDirectory is the name of the directory that should be used as the current directory by the printing application
nOpenMode indicates the mode of the printing application (minimised etc.)
Various modes can be selected using the #define's in printerAPI.ch
Returns TRUE if successful
This function accepts a file name, and instructs Windows to print the file using the default application using file-type associations.
GetDefaultPrinter()
GetDefaultPrinter() -> cPrinter
Returns the name of the current default printer
Win9x Under Win9x/ME, this returns a device string in the format "name, driver, port"
SetDefaultPrinter()
SetDefaultPrinter( cPrinter ) -> lOk
cPrinter is the name of the printer to make the default printer
Returns TRUE if the named printer was successfully set as the default printer
The parameter should have been derived from a previous call to either EnumPrinters() or GetDefaultPrinter()
Win9x Under Win9x/ME cPrinter should be a device string. See GetDefaultPrinter() for details.
EnumPrinters()
EnumPrinters() -> aPrinters
Returns an array of printer names of all installed printers
WinNT e.g. {"HP Laserjet 4i", "Epson Stylus C600" }
Win9x e.g. {"HP Laserjet 4i,HPLDRV,\\srv1\hplj4", "Epson Stylus C600,EPSDRV,LPT2"}
GetPrinterNameFromString()
GetPrinterNameFromString( cPrinter ) -> cPrinterName
Returns a printer name
This function accepts both a WinNT/W2K/XP printer name, and a Win9x/ME device string (which also includes the driver name and port name), and returns just the printer name. This allows you to retrieve a printer name without having to consider which version of Windows is running.
e.g.
print names of all installed printers
// does not print device and port names on Win9x/ME
aPrinters := EnumPrinters()
for i := 1 to len(aPrinters)
? GetPrinterNameFromString( aPrinters[i] )
e.g. "HP Laserjet 4i"
next
--------------------------------------------------------------------------------
History
18th Sep 2003 Added WinAPIOpen() routine, which will cause the file to be opened in view/edit mode by the application registered to handle the filetype. (e.g. .html to IE/Mosaic etc, .doc to WinWord etc. as appropriate for your system) 28th Jly 2003 Fix to C++ routine - I'd forgotten to close the printer
- thanks to Michael Hoffman for spotting this. 27th Jly 2003 Fix to C++ routine (I'd accidentally deleted the line which freed memory allocated from the Windows heap) 25th Jly 2003 Fixed potential GC problem by gathering Win9x printer info via C++ routine.
Since the C++ routine cannot be compiled unless you have a suitable compiler, the package now creates PrinterAPI.DLL, which should make it easier to use and install. 23rd Jly 2003 Initial Win9x compatible release 10th Feb 2003 Original release, worked only on NT class machines
--------------------------------------------------------------------------------
Acknowledgements
My thanks to those who tested the Win9x compatibility routines for me (alphabetical): Edgar Borger
Regan Cawkwell
Greg Doran
Osvaldo Ramirez
Terry Wolfe
This message includes the following attachments:
printerapi.zip
5/8/2008 11:15 AM UTC
Print Screen App
Pablo Botella
Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
********************************************************************
* CLASS MxPrintScreen
********************************************************************
* Copyright:
* Joe Carrick - 03/07/2000
*
* Note: This implementation clears the Windows Clipboard.
* This is necessary to avoid printing the Window continuously.
********************************************************************
This message includes the following attachments:
PrntScrnApp.zip
Page 1 of 2
Next >