﻿<rss version="2.0"><channel><title>xfree.resources (readonly)</title><link>http://news.xb2.net/xfree.resources</link><description>xfree.resources (readonly)</description><lastBuildDate>Sun, 07 Sep 2008 17:25:33 GMT</lastBuildDate><generator>MPNews http://www.messagepixels.com</generator><ttl>10</ttl><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/37/ot4xb+-+snapshots.html</guid><title>ot4xb - snapshots</title><pubDate>Wed, 7 May 2008 10:09:25 +0200</pubDate><link>http://news.xb2.net/xfree.resources/37/ot4xb+-+snapshots.html</link><comments>http://news.xb2.net/xfree.resources/37/ot4xb+-+snapshots.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Hello,

As you have notice the lastest ot4xb &amp;quot;oficial&amp;quot; release in my site is still a bit out to date ( June 2006 ). The idea was to release complete packages including updated docs and samples, the trouble is that I had put more work in the source code that in the documentation, so I've waiting to have an update docs to release a new &amp;quot;oficial&amp;quot; build.

In order to give access to the latest builds ( and sources) in the meantime I have prepared &amp;quot;oficial&amp;quot; packages  I will drop the ZIPs here.

Regards,
Pablo Botella

------------------------------------------------------------
Hola,

Como probablemente os habreis dado cuenta, la &amp;#250;ltima versi&amp;#243;n &amp;quot;oficial&amp;quot; que tengo publicada en mi sitio est&amp;#225; algo desfasada ( Junio de 2006). Mi idea era poder publicar los paquetes completos inclullendo ejemplos y documentacion actualizada, el problema es que siempre avanzo m&amp;#225;s deprisa escribiendo el c&amp;#243;digo que la documentaci&amp;#243;n, por eso he estado retrasando la publicaci&amp;#243;n de nuevas versiones &amp;quot;oficiales&amp;quot; esperando tener la documentaci&amp;#243;n actualizada.

Ire metiendo aqu&amp;#237; ZIPs con los &amp;#250;ltimos builds ( y las fuentes), para que podais acceder a ellas mientras voy preparando los paquetes &amp;quot;oficiales&amp;quot;.

Saludos,
Pablo Botella&lt;/pre&gt;</description><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/37</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/41/Phil+Ide+Packages.html</guid><title>Phil Ide Packages</title><pubDate>Wed, 7 May 2008 15:45:35 +0200</pubDate><link>http://news.xb2.net/xfree.resources/41/Phil+Ide+Packages.html</link><comments>http://news.xb2.net/xfree.resources/41/Phil+Ide+Packages.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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&amp;#241;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
------------------------------------------------------------------------&lt;/pre&gt;</description><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/41</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/42/XML.html</guid><title>XML</title><pubDate>Wed, 7 May 2008 15:46:33 +0200</pubDate><link>http://news.xb2.net/xfree.resources/42/XML.html</link><comments>http://news.xb2.net/xfree.resources/42/XML.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;&lt;/pre&gt;</description><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/42</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/43/XML+%5b+Modified+by+Javier+(Syga+System)+%5d.html</guid><title>XML [ Modified by Javier (Syga System) ]</title><pubDate>Wed, 7 May 2008 15:49:13 +0200</pubDate><link>http://news.xb2.net/xfree.resources/43/XML+%5b+Modified+by+Javier+(Syga+System)+%5d.html</link><comments>http://news.xb2.net/xfree.resources/43/XML+%5b+Modified+by+Javier+(Syga+System)+%5d.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/43/attachments/0/xmlzio.zip" length="188831" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/43</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/44/XbFPT.html</guid><title>XbFPT</title><pubDate>Wed, 7 May 2008 17:38:54 +0200</pubDate><link>http://news.xb2.net/xfree.resources/44/XbFPT.html</link><comments>http://news.xb2.net/xfree.resources/44/XbFPT.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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.
--------------------------------------------------------------------&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/44/attachments/0/xbftp.zip" length="14260" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/44</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/45/XbSSL+-+SSL+Wrapper+for+OpenSSL+and+ASINET.html</guid><title>XbSSL - SSL Wrapper for OpenSSL and ASINET</title><pubDate>Wed, 7 May 2008 17:49:05 +0200</pubDate><link>http://news.xb2.net/xfree.resources/45/XbSSL+-+SSL+Wrapper+for+OpenSSL+and+ASINET.html</link><comments>http://news.xb2.net/xfree.resources/45/XbSSL+-+SSL+Wrapper+for+OpenSSL+and+ASINET.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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 
--------------------------------------------------------------------&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/45/attachments/0/xbssl.zip" length="4217" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/45</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/46/ABS182.html</guid><title>ABS182</title><pubDate>Wed, 7 May 2008 18:08:41 +0200</pubDate><link>http://news.xb2.net/xfree.resources/46/ABS182.html</link><comments>http://news.xb2.net/xfree.resources/46/ABS182.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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.
--------------------------------------------------------------------&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/46/attachments/0/abs182.zip" length="1022" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/46</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/47/AJAX.html</guid><title>AJAX</title><pubDate>Wed, 7 May 2008 18:12:57 +0200</pubDate><link>http://news.xb2.net/xfree.resources/47/AJAX.html</link><comments>http://news.xb2.net/xfree.resources/47/AJAX.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Author : Phil Ide
Created: 18-Jun-2005
--------------------------------------------------------------------
Using AJAX with WAA and javascript&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/47/attachments/0/ajaxsrc.zip" length="3013" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/47</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/48/Smart+Object.html</guid><title>Smart Object</title><pubDate>Wed, 7 May 2008 23:15:02 +0200</pubDate><link>http://news.xb2.net/xfree.resources/48/Smart+Object.html</link><comments>http://news.xb2.net/xfree.resources/48/Smart+Object.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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() -&amp;gt; nSize


To create a structure, you use this syntax:

STRUCTURE &amp;lt;structName&amp;gt;
   &amp;lt;type&amp;gt; &amp;lt;membername&amp;gt; [SIZE &amp;lt;nSize&amp;gt;]
   [&amp;lt;type&amp;gt; &amp;lt;membername&amp;gt; [SIZE &amp;lt;nSize&amp;gt;]]
   [STRUCT &amp;lt;membername&amp;gt; AS &amp;lt;structureName&amp;gt;]
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.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/48/attachments/0/smartobjects_2005_09_05.zip" length="9998" type="application/octet-stream" /><enclosure url="http://news.xb2.net/xfree.resources/48/attachments/1/smartobjects_2003_12_18.zip" length="8977" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/48</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/49/Gradient.html</guid><title>Gradient</title><pubDate>Wed, 7 May 2008 23:20:51 +0200</pubDate><link>http://news.xb2.net/xfree.resources/49/Gradient.html</link><comments>http://news.xb2.net/xfree.resources/49/Gradient.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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 := &amp;quot;[Rectangle] graduate from left to right&amp;quot;
   oDlg:sysmenu := TRUE
   oDlg:tasklist := TRUE

   oDlg:setColor(1,14,23,92)
   oDlg:setColor(2,198,205,254)

   oDlg:create()
   return oDlg&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/49/attachments/0/gradient.zip" length="2739" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/49</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/50/capwin.html</guid><title>capwin</title><pubDate>Wed, 7 May 2008 23:36:26 +0200</pubDate><link>http://news.xb2.net/xfree.resources/50/capwin.html</link><comments>http://news.xb2.net/xfree.resources/50/capwin.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Author : Phil Ide
Created: 17-Oct-2003
--------------------------------------------------------------------
There are three functions:

CaptureWindow(hWnd) -&amp;gt; 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 ) -&amp;gt; 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 ) -&amp;gt; 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 &amp;quot;printWin.ch&amp;quot;

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.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/50/attachments/0/capwin.zip" length="12345" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/50</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/51/FReader.html</guid><title>FReader</title><pubDate>Wed, 7 May 2008 23:39:50 +0200</pubDate><link>http://news.xb2.net/xfree.resources/51/FReader.html</link><comments>http://news.xb2.net/xfree.resources/51/FReader.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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(&amp;lt;n&amp;gt;) method,
where &amp;lt;n&amp;gt; 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(&amp;lt;n&amp;gt;), but only if the file has
previously been ::examine()'d or the target line has already been read.

METHODS and IVARS
=================
Class Methods
-------------
:new(&amp;lt;cFile&amp;gt; [,&amp;lt;cEOLToken&amp;gt;]) -&amp;gt; oFileReader

   Creates an instance of the FileReader() class.

   &amp;lt;cFile&amp;gt; is the name of the file to access, and may include a full path.

   &amp;lt;cEOLToken&amp;gt; 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() -&amp;gt; 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() -&amp;gt; self

   As for :configure() but also closes the file handle.


Navigation Methods
------------------
:goBottom() -&amp;gt; self

   Sets the last (known) line as the current line.

:goTo(&amp;lt;n&amp;gt;) -&amp;gt; lSuccess

   Sets the current line pointer to line &amp;lt;n&amp;gt;.  Returns TRUE if successful.

:goTop() -&amp;gt; self

   Sets the first line as the current line.

:rewind() -&amp;gt; lSuccess

   Decrements the current line pointer.  Returns TRUE if successful.

:skip(&amp;lt;n&amp;gt;) -&amp;gt; nSkipped

   Advances the current line pointer by &amp;lt;n&amp;gt; lines if positive, or
   decrements the line pointer if negative.  Returns the actual number of
   lines it was possible to skip.

:goPosition(&amp;lt;n&amp;gt;) -&amp;gt; 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() -&amp;gt; nEofPos

   Returns the offset of the end-of-file - in other words, the file size.

:examine() -&amp;gt; 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() -&amp;gt; nCurLine

   Returns the current line number.

:reexamine() -&amp;gt; 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() -&amp;gt; cLine

   Returns the current line of data.  The pointer indicating the current
   line is advanced by one.

:position() -&amp;gt; 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() -&amp;gt; cLine

   Rereads the data for the current line without advancing the current
   line pointer.

:fileName() -&amp;gt; cFile

   Returns the full name (including path if supplied) of the file being
   accessed.

:baseFileName() -&amp;gt; cFileName

   Returns the file name of the file being accessed without any path
   information.

XbpBrowse specific methods
--------------------------
:configureXbpBrowse( &amp;lt;oBrowse&amp;gt; ) -&amp;gt; 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()&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/51/attachments/0/freader.zip" length="7202" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/51</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/52/iniedit.html</guid><title>iniedit</title><pubDate>Wed, 7 May 2008 23:47:02 +0200</pubDate><link>http://news.xb2.net/xfree.resources/52/iniedit.html</link><comments>http://news.xb2.net/xfree.resources/52/iniedit.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/52/attachments/0/iniedit.zip" length="9603" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/52</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/53/INI+Files.html</guid><title>INI Files</title><pubDate>Wed, 7 May 2008 23:50:49 +0200</pubDate><link>http://news.xb2.net/xfree.resources/53/INI+Files.html</link><comments>http://news.xb2.net/xfree.resources/53/INI+Files.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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(&amp;quot;win.ini&amp;quot;)

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(&amp;quot;Desktop&amp;quot;, 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 &amp;quot;key=value&amp;quot;.
 AList must have already been initialised to {}.

 Example: IniFile:ReadSectionValues(&amp;quot;Desktop&amp;quot;, 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(&amp;quot;Options&amp;quot;, &amp;quot;LastUser&amp;quot;, &amp;quot;Mab&amp;quot;)

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(&amp;quot;Options&amp;quot;, &amp;quot;Width&amp;quot;, 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(&amp;quot;Options&amp;quot;, &amp;quot;New&amp;quot;, .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(&amp;quot;Options&amp;quot;, &amp;quot;LastUser&amp;quot;, &amp;quot;Mab&amp;quot;)

DeleteKey(ASection, AKey)
 Removes the given key from the ini file.

 Example: IniFile:DeleteKey(&amp;quot;Options&amp;quot;, &amp;quot;LastUser&amp;quot;)

EraseSection(ASection)
 Removes the given section from the ini file.

 Example: IniFile:EraseSection(&amp;quot;Options&amp;quot;)&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/53/attachments/0/Inifiles.zip" length="2508" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/53</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/54/IPC+Signal.html</guid><title>IPC Signal</title><pubDate>Wed, 7 May 2008 23:54:37 +0200</pubDate><link>http://news.xb2.net/xfree.resources/54/IPC+Signal.html</link><comments>http://news.xb2.net/xfree.resources/54/IPC+Signal.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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

   &amp;gt;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)&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/54/attachments/0/ipcsignal.zip" length="3742" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/54</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/55/JS+Recruiter.html</guid><title>JS Recruiter</title><pubDate>Wed, 7 May 2008 23:59:44 +0200</pubDate><link>http://news.xb2.net/xfree.resources/55/JS+Recruiter.html</link><comments>http://news.xb2.net/xfree.resources/55/JS+Recruiter.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/55/attachments/0/jsr.zip" length="84176" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/55</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/56/Load+From+URL.html</guid><title>Load From URL</title><pubDate>Thu, 8 May 2008 00:15:11 +0200</pubDate><link>http://news.xb2.net/xfree.resources/56/Load+From+URL.html</link><comments>http://news.xb2.net/xfree.resources/56/Load+From+URL.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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&amp;amp;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 &amp;lt;cHttpHeaders&amp;gt; parameter of
   LoadFromUrl(), or set default headers withthis function and context
   specific headers with &amp;lt;cHttpHeaders&amp;gt;.

   The headers should be formatted in the same way as &amp;lt;cHttpHeaders&amp;gt;.  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 &amp;quot;Accept:
         text/*&amp;quot; followed by &amp;quot;Accept: audio/*&amp;quot; with this flag results in the
         formation of the single header &amp;quot;Accept: text/*, audio/*&amp;quot;. 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: &amp;lt;15h6c878vias2.dlg@idep.org.uk&amp;gt;

   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.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/56/attachments/0/lfu1150.zip" length="16757" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/56</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/57/piCommon+-+general+purpose+command+extensions.html</guid><title>piCommon - general purpose command extensions</title><pubDate>Thu, 8 May 2008 00:21:06 +0200</pubDate><link>http://news.xb2.net/xfree.resources/57/piCommon+-+general+purpose+command+extensions.html</link><comments>http://news.xb2.net/xfree.resources/57/piCommon+-+general+purpose+command+extensions.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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.
--------------------------------&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/57/attachments/0/picommon.zip" length="1949" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/57</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/58/piWis+-+emulate+some+of+the+functionality+of+WIS.html</guid><title>piWis - emulate some of the functionality of WIS</title><pubDate>Thu, 8 May 2008 00:25:01 +0200</pubDate><link>http://news.xb2.net/xfree.resources/58/piWis+-+emulate+some+of+the+functionality+of+WIS.html</link><comments>http://news.xb2.net/xfree.resources/58/piWis+-+emulate+some+of+the+functionality+of+WIS.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;/*****************************
* Source : piWis.prg
* System : &amp;lt;unkown&amp;gt;
* 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, &amp;quot;tr&amp;quot; )

 ..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) &amp;lt;span&amp;gt; and &amp;lt;div&amp;gt; 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.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/58/attachments/0/piwis.zip" length="2226" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/58</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/59/Printer+API.html</guid><title>Printer API</title><pubDate>Thu, 8 May 2008 13:08:10 +0200</pubDate><link>http://news.xb2.net/xfree.resources/59/Printer+API.html</link><comments>http://news.xb2.net/xfree.resources/59/Printer+API.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
PrinterAPI
Program  : &amp;lt;none, general&amp;gt;
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 &amp;quot;print&amp;quot; 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] ) -&amp;gt; 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(&amp;quot;default.html&amp;quot;) // load the file into a web browser
  WinAPIOpen(&amp;quot;default.rtf&amp;quot;)  // load the file into a rich-text editor
  WinAPIOpen(&amp;quot;MyDialog.XFF&amp;quot;) // edit a Dialog definition in Xbase++'s Form Designer!

WinApiPrint()

WinApiPrint( cFile, [cParms], [cDirectory], [nOpenMode] ) -&amp;gt; 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() -&amp;gt; cPrinter
Returns the name of the current default printer

Win9x Under Win9x/ME, this returns a device string in the format &amp;quot;name, driver, port&amp;quot; 

SetDefaultPrinter()

SetDefaultPrinter( cPrinter ) -&amp;gt; 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() -&amp;gt; aPrinters
Returns an array of printer names of all installed printers

WinNT e.g. {&amp;quot;HP Laserjet 4i&amp;quot;, &amp;quot;Epson Stylus C600&amp;quot; }

Win9x e.g. {&amp;quot;HP Laserjet 4i,HPLDRV,\\srv1\hplj4&amp;quot;, &amp;quot;Epson Stylus C600,EPSDRV,LPT2&amp;quot;} 

GetPrinterNameFromString()

GetPrinterNameFromString( cPrinter ) -&amp;gt; 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. &amp;quot;HP Laserjet 4i&amp;quot;
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&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/59/attachments/0/printerapi.zip" length="20884" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/59</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/60/Print+Screen+App.html</guid><title>Print Screen App</title><pubDate>Thu, 8 May 2008 13:15:37 +0200</pubDate><link>http://news.xb2.net/xfree.resources/60/Print+Screen+App.html</link><comments>http://news.xb2.net/xfree.resources/60/Print+Screen+App.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;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.
********************************************************************&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/60/attachments/0/PrntScrnApp.zip" length="58727" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/60</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/61/Shell+To+Buffer.html</guid><title>Shell To Buffer</title><pubDate>Fri, 9 May 2008 10:38:33 +0200</pubDate><link>http://news.xb2.net/xfree.resources/61/Shell+To+Buffer.html</link><comments>http://news.xb2.net/xfree.resources/61/Shell+To+Buffer.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Package: Shell2Buffer
Author : Phil Ide
Version: 1.0

(c)Copyright Phil Ide 2005, All Rights Reserved

Sometimes you want some information output by another application.  For
example, to see which logical drives are mapped to SUBST drives, you can
do the following at the command prompt:

  C:\&amp;gt;SUBST

This then lists the SUBST'ed drives and where they are mapped to.

To get this information in Xbase++, you would typically use the
RunShell() command with redirection to a file:

  RunShell(&amp;quot;SUBST &amp;gt; mappings.txt&amp;quot;)

You can then read mappings.txt into a variable and analyse it.

This package contains a function called ShellOutputToBuffer().  What
this does is exactly the same as RunShell() except it redirects the
output of the external process back into an Xbase++ buffer.  This buffer
is then emptied into a variable and returned to your calling
application.

Caveats:
   1. Only guaranteed to work on NT, W2K, XP and W2K3.  May work on W95/98/ME
      (Microsoft Platform SDK documentation suggests that this should
      work on all Windows versions from W95/NT onwards, but also says it
      doesn't work except on NT class machines!  Confused?  You bet.)

   2. Currently only works Asynchronously.
      When the external application is launched, the Xbase++ parent
      application halts until the external application terminates.  This
      is necessary because the external program may not deliver all
      its data in one go, and the Xbase++ parent application has no
      way of knowing when the external program has finished.

   3. Only a limited amount of data can be returned by the external
      application.  This is because the output buffer shell the external
      application is running in is of limited (but undetermined) size.
      Once this buffer becomes full, and if the application is still
      trying to write to it, the external application may hang until
      the buffer has been emptied.  If the external application hangs,
      then the parent application will also hang until the shell the
      external application is running in has been destroyed.

Points (2) and (3) can be remedied by monitoring the status of the
external application through its processHandle.  Thus then it would be
possible to run synchronously and have an indefinite amount of data
(up to the 4Gb or system resources limit, whichever is the lesser) fed
back from the external application.

I may create a synchronous version in the future - if you want it, let
me know.  If I don't get queries on something, I assume it is not
required and put it on a back-burner.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/61/attachments/0/shell2buffer.zip" length="3190" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/61</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/62/USER32+APIs.html</guid><title>USER32 APIs</title><pubDate>Fri, 9 May 2008 10:41:05 +0200</pubDate><link>http://news.xb2.net/xfree.resources/62/USER32+APIs.html</link><comments>http://news.xb2.net/xfree.resources/62/USER32+APIs.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
**************************************************************************
*
*  Module:     WinDefines.ch
*  Category:   Define Listing
*  Used By:    WinInfo Project
*  Author:     Greg Doran, Dublin Ireland
*  Version:    1.0
*  Date:       2nd.Feb.2002
*
**************************************************************************&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/62/attachments/0/User32APIs.zip" length="12609" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/62</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/63/WarFPTd.html</guid><title>WarFPTd</title><pubDate>Fri, 9 May 2008 10:43:41 +0200</pubDate><link>http://news.xb2.net/xfree.resources/63/WarFPTd.html</link><comments>http://news.xb2.net/xfree.resources/63/WarFPTd.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Author : Phil Ide
Created: 10/05/2004
--------------------------------------------------------------------
This class allows you to manipulate the WAR-FTP daemon from an 
Xbase++ application.  Services it gives you are:

  o Add new user
  o Retrieve user records
  o (Re)-Configure users (password, permissions, paths etc)
  o Delete users
  o shutdown server:
    - wait for users to logoff (deny new users) then shutdown
    - kick users and shutdown without waiting

To understand what the functions are and how to use them, see the
WARFTPD developers documentation (you'll also need WARFTPD, but I
guess you already knew that ;-)

In most instances, the methods return TRUE or FALSE depending upon
success or failure of the operation.  Exceptions to this are:

   WarFTPDApi:init() -&amp;gt; self
   WarFTPDApi:openSession() -&amp;gt; nErr ( 0 = SUCCESS )
   WarFTPDApi:lookupUser() -&amp;gt; nUserHandle
   WarFTPDApi:destroy() -&amp;gt; self

Additionally, most operations will set an errorlevel in WarFTPDApi:nErr.
A value of 0 indicates success.  Other values indicate the error
condition, and descriptions can be determined by examining the
WARAPI_ERR_* constants in War170API.ch.  Methods that do NOT set the
errorlevel are:

   WarFTPDApi:releaseUserHandle()
   WarFTPDApi:destroy()


History:
==========
v1.1
    o Fixed password issue
      WarFTPDApi:openSession() did not accept a username/password

    o Fixed WarFTPDApi:init()
      Did not return 'self' (not actually a problem, but fixed anyway)

    o Added extra info to 'docs' to explain features of the class&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/63/attachments/0/warftpd.zip" length="2777" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/63</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/64/WinProp.html</guid><title>WinProp</title><pubDate>Fri, 9 May 2008 10:46:28 +0200</pubDate><link>http://news.xb2.net/xfree.resources/64/WinProp.html</link><comments>http://news.xb2.net/xfree.resources/64/WinProp.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Author : Phil Ide
Created: 10/09/2003
--------------------------------------------------------------------
Toggle window properties
   Example:

   A. To turn off (disable) the Maximise button:

       SetWindowPropertyOff( oDlg, WS_MAXIMIZEBOX )

   B. To turn off (disable) the Minimise button:

       SetWindowPropertyOff( oDlg, WS_MINIMIZEBOX )

   C. To turn off the max and min buttons:

       SetWindowPropertyOff( oDlg, WS_MAXIMIZEBOX+WS_MINIMIZEBOX )

   Notes:
   Sample A only disables the maximise button.
   Sample B only disables the minimise button.
   Sample C actually removes the minimise and maximise buttons.
   The inference here is that one cannot exist without the other.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/64/attachments/0/winprop.zip" length="1229" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/64</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/65/Word+Document.html</guid><title>Word Document</title><pubDate>Fri, 9 May 2008 10:48:10 +0200</pubDate><link>http://news.xb2.net/xfree.resources/65/Word+Document.html</link><comments>http://news.xb2.net/xfree.resources/65/Word+Document.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
WordDocument
------------
Author: Phil Ide

Description:

   The class WordDocument and it's descendants are designed
   for print-and-die processing.  They load the source file,
   perform any data exchange, print the document using MS-Word,
   then kill MS-Word.  If you wish to keep the MS-Word instance
   alive, then you will have to subclass WordDocument and change
   the behaviour in the print() method.


In simple use, create a class to perform the data exchange (i.e. the
methods of the class return the data that is to be embedded in the
document) which inherits from WordDocument.

Next create an RTF file (using MS-Word), and embed tokens where you want
the data to be placed.  Tokens are in the form $!n$ where &amp;lt;n&amp;gt; is a
unique identifier (I use a number - nice and simple).

Part of the class definition should populate an array (which is an
iVar of WordDocument) with code blocks which refer to the methods
returning data.  The correlation between the methods and the tokens is
established in the array, and is based upon ordinal position:

   ::aMList := { {|o| o:someMethod() },;
                 {|o| o:someOtherMethod() },;
                 {|o| o:foo() };
               }

With the above array, the data is transposed as follows:

   Token    Method returning Data
   ------------------------------
   $!1$     ::someMethod()
   $!2$     ::someOtherMethod()
   &amp;#163;!3$     ::foo()

Having created the class and RTF document, usage is very simple:


  // assume your WordDocument subclass is called MyDocument
  //
  oDoc := MyDocument():new( 'template.rtf' )
  oDoc:detonate()

You can gain finer control over the print process:

  oDoc := MyDocument():new( 'template.rtf' )
  oDoc:exec() // embed data
  oDoc:configurePrinter(,&amp;quot;HPLJ5&amp;quot;) // set printer
  oDoc:print()

It is also possible to set a file as the target for the print, but
this is print-driver dependant (the target filename is passed as the
first parameter to :configurePrinter() or the second parameter of the :
init() method).

The code is compatible with all versions of Xbase++ back to at least 1.6
and including 1.90 (so hopefully beyond 1.90 too).  By default, if
compiled with Xbase++ v1.90, it will use the MS-Word ActiveX object to
perform the print process, otherwise it will use Windows File
Associations (which may result in something other than MS-Word being
used).

Caveats:
--------
This works perfectly in my environment for the usage I put it to.  In
other situations, bugs may be detected, in which case I will gladly
fix them.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/65/attachments/0/WordDocument.zip" length="84306" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/65</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/66/XbPipes.html</guid><title>XbPipes</title><pubDate>Fri, 9 May 2008 10:51:52 +0200</pubDate><link>http://news.xb2.net/xfree.resources/66/XbPipes.html</link><comments>http://news.xb2.net/xfree.resources/66/XbPipes.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
 &amp;#169;Phil Ide 2002-2003 
Based on work derived from dbfServer
&amp;#169;Jack Duijf &amp;amp; Phil Ide, 2002-2003. 
Sockets.prg code extracted from experimental code for dbfServer 
XbPipes provides Named- and UnNamed-Pipe functionality to Xbase++ 
--------------------------------------------------------------------&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/66/attachments/0/XbPipes.zip" length="50847" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/66</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/67/XbpPng.html</guid><title>XbpPng</title><pubDate>Fri, 9 May 2008 10:53:30 +0200</pubDate><link>http://news.xb2.net/xfree.resources/67/XbpPng.html</link><comments>http://news.xb2.net/xfree.resources/67/XbpPng.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
XbpPNG
Author: Phil Ide
Copyright Phil Ide 2003, All Rights Reserved.
Version: 1.0

XbpBitmap2() inherits from XbpBitmap, so can be used as a complete
replacement.  The only difference is when you attempt to save the
image as a diskfile specifying XBPBMP_FORMAT_PNG as the format to save
as, or if you request that any existing image file of the same name is
overwritten.

When you specify the format as PNG, it creates the image file
according to the PNG specifications, using ZLib as the compression
library (note that ZLib is the 'official' compression library for PNG).

Some small enhancements have been made over XbpBitmap():

  1. Creation of the image file is done in a fraction of the time
  2. You can indicate that if the file already exists, it should be
     overwritten (XbpBitmap() will not overwrite). Note that this
     works regardless of the image format requested!
  3. You can specify a title and a description to be embedded within the
     image file.  The title is added in a tEXt chunck as plain text, the
     description (which can be of any length) is embedded in a zTXt
     chunk, and is compressed.

Syntax:
  oBmp:saveFile( cImgFile, nImgFormat, nCompressLevel,; // standard opts
                 lOverWrite, cTitle, cDescription )     // extended opts

The default for lOverWrite is FALSE, maintaining consistency with
XbpBitmap().

Limitations:
------------
v1.0 can only create PNG files for images with 256 colours or less.
If the image has more than 256 colours, then the saving of the image
is passed up to the parent class - XbpBitmap.  This means that saving
files with more than 256 colours will still take as long as before,
and you will not be able to embed a title or description.  Note however,
that the test for the number of colours occurs _after_ any existing disk
image file is erased (if the lOverWrite flag is TRUE).  Therefore, it is
possible to overwrite an existing PNG file whatever the number of
colours present.

The reason XbpBitmap2() doesn't handle images with more than 256
colours, is simply because I haven't figured out how to convert the
raw image data into the correct format yet.

In version 2.0, I will resolve this problem, plus add these
enhancements:

1.  Allow arbitrary text data chunks to be added.  This includes the
    complete list of reserved keyword chunks:

    Keyword         Implemented
    ---------------------------
    Title           Yes
    Author          -
    Description     Yes
    Copyright       -
    Creation Time   -
    Software        Yes
    Disclaimer      -
    Warning         -
    Source          -
    Comment         -

    It will also be possible to add arbitrary new keywords.

2.  Specify complete alpha channels for each pixel.
    PNG allows an alpha channel to be specified for each pixel in the
    image.  The alpha channel is often referred to as the transparency
    flag, however that is a very misleading misconception.  An alpha
    channel specifies the opaqueness of a colour, where one extreme
    value indicates full opacity and the other extreme value indicates
    complete transparency.  Intermediate values offer degrees of opacity
    (or transparency, depending upon how you look at it).

    The GIF image format allows you to specify a single colour which
    is to be treated as transparent, whereas PNG allows you to specify
    an alpha channel for _each pixel_ in the image.

3.  PNG also supports a tRNs chunk, which allows you to specify an alpha
    channel to be applied against individual colours (thereby
    affecting all pixels rendered in that colour).  As with the full
    alpha channel (affecting pixels), the tRNs chunk allows you to
    define an alpha channel for each colour in the palette (which
    means it can only be applied to images of 256 colours or less).

    I wanted to implement this in v1.0, but I need to investigate the
    possibilities involved with grey-scale and monochrome images.

Special Note:
-------------
Creating a PNG file from a manually created image (e.g. a graph) that
was created by drawing to an XbpBitMap() or XbpBitmap2() object, will
create a 65M colour image.  This is because there is no palette
associated with the image.

If you create a palette array {{R,G,B},...} and add that to the object
prior to saving, then the image can be saved as 256 colour image,
which is much faster when saving as a PNG image.  Unfortunately,
XbpBitmap() does not have the ability to add a palette array.

In the next version, I'll work around this problem and add this ability.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/67/attachments/0/xbppng.zip" length="90197" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/67</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/68/xcExcell.html</guid><title>xcExcell</title><pubDate>Fri, 9 May 2008 10:55:33 +0200</pubDate><link>http://news.xb2.net/xfree.resources/68/xcExcell.html</link><comments>http://news.xb2.net/xfree.resources/68/xcExcell.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------
Class xcExcel
Uses xcExcelCell
xcExcelProperty
----------------------------------------------------
Author Phil Ide
Version 1.0
Date 25th Sept 2004
----------------------------------------------------
Synopsis
At this stage of development, the xcExcel class allows you to generate a spreadsheet in
memory. The spreadsheet is optimised for minimum memory consumption. The sheet itself
consumes a tiny amount of memory (just a few bytes), and each cell consumes just a few
bytes plus whatever it's value requires.
I have at this stage identified a simplified cell class, the implementation of which requires just
a few small changes to both the cell and the sheet classes.
It is important to remember that despite the names of the classes, the spreadsheet created is
completely generic. When the sheet is saved to disk, only then does the format dictate which
spreadsheet programs can read it. It is possible to save the sheet in formats which can be
understood by Excel, Lotus-1-&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/68/attachments/0/xcexcel.zip" length="38757" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/68</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/69/XbPgSql.html</guid><title>XbPgSql</title><pubDate>Fri, 9 May 2008 10:59:39 +0200</pubDate><link>http://news.xb2.net/xfree.resources/69/XbPgSql.html</link><comments>http://news.xb2.net/xfree.resources/69/XbPgSql.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR) and Hector Pezoa
--------------------------------------------------------------------
Author : Phil Ide
Created: 02/02/2004
--------------------------------------------------------------------
# XbPgSQL - PostGreSQL interface classes

These classes provide direct communication with the PG server,
much, *much* faster than using ODBC.

The C support routine psqlsupp.c merely de-references pointers and
returns the string the pointer points to.

To understand how to use ths classes, please read the PG docs,
particularly the following section:

PostgreSQL 7.3.1 Programmer's Guide
 Preface
 I. Client Interfaces          &amp;lt;--- read this!
 II. Server Programming
 III. Procedural Languages

If you know _anything_ about SQL, this should make sense to you. As far
as I can ascertain, everything works as expected.  Any feedback is
welcome.

=====================
History
=====================
v1.2
   Fix for PGSql:execParams() method
   
v1.1
   Fix for two PGResult() methods not dereferencing the pointer returned

v1.0

Legend: [c] = PGSql() method, [r] = PGResult() method
        [b] = method of both classes

   [b] PQescapeString  // was in PGSql()
   [b] PQescapeBytea   // was in PGSql()
   [b] PQunescapeBytea // was in PGSql()

   [b] PQmakeEmptyPGResult // this returns a new PGResult object
                           // (documentation change)

   // new asynchronous functions
   [r] PQsetnonblocking
   [r] PQisnonblocking
   [r] PQsendQuery
   [r] PQgetResult
   [r] PQconsumeInput
   [r] PQisBusy
   [r] PQflush
   [r] PQsocket
   [r] PQrequestancel

   //debugging
   [r] PQtrace
   [r] PQuntrace

With this release, I consider the initial implementation complete, and
have therefore set the version number to 1.0. The remaining functions
are not so simple to implemnt (usually because they return
structures), but if you have a desperate need for one I haven't
implemented, let me know.

=====================
v0.4

Added the following functions from libpq:

Legend: [c] = PGSql() method, [r] = PGResult() method
        [b] = method of both classes

   [c] PQsetdbLogin
   [c] PQconnectStart   // non-blocking connection
   [c] PQconnectPoll    // non-blocking connection
   [c] PQresetStart     // non-blocking connection
   [c] PQresetPoll      // non-blocking connection

   [r] PQresultStatus
   [r] PQresStatus
   [b] PQmakeEmptyPGResult // this is a method of PGResult
                           // and returns a new PGResult object
   [r] PQescapeString
   [r] PQescapeBytea
   [r] PQunescapeBytea

   [r] PQfmod
   [r] PQbinaryTuples

You will notice that some of the high-level non-blocking functions
have been added.  The next release of this library will include all
the lower-level non-blocking functions (including async notification
methods), the tracing and control functions.  At that point, I'll
consider this library to be complete.  If you have a need for any of the
other functions not covered by this list, let me know.  For the most
part, the remaining functions are unlikely to be used or required.

I've removed the refrence to piCommon.ch and included the only
translation used in that file.

To the sample program, SQLTEST.EXE, I've added some additional
functionality to provide more feedback and flexibility.  For example,
the query should now be loaded from a text file, and should be named
on the command-line using the /q parameter.  To load the file query.sql,
use:
  SQLTEST.EXE /qquery.sql

If the query contains a comment between /* and */ markers, it will
display the comment before firing the query.  The query can acept
parameters, which should also be specified on the command-line.  If
the query accepts 3 parameters, then the command-line will look like
this:

  SQLTEST.EXE /qquery.sql parm1 parm2 parm3

Inside the query, the parameters will replcae instances of %1, %2 etc.
This parameter replacement also occurs inside the comment block so:

/* Get number of hire years for %1 in period %2-%3
{
   %a/365
}
*/
select sum(_days) from k%1_db where _date_out &amp;gt;= '%1' and
_date_in &amp;lt;= '%2';

Will display the comment in the block and replace the parameters
accordingly.

Insode the comment block, you can also see a {} construct.  If this
exists (the '{' and '}' must appear on seperate lines), then the
resulting value returned by the query (first tuple, first column) is
used to replace '%a', and the result of this equation is displayed
instead of the browse.

Note that this is an incomplete implementation of this facility, just
showing you some of the possibilities available if you are prepared to
pre-parse the stored query.

I have also hacked psqlsupp.obj so that it no longer requests uuid.lib.

Lastly, connection info is now supplied in pgconfig.cfg, which you
should edit to suit your needs.  Note that instead of host= you can
use hostaddr=, but you shouldn't use both.


=====================
v0.3

In v0.2, I wasn't sure whether the dynamic column names were case
sensitive or not.  Now I am sure, and it is INSENSITIVE.  Therefore:

   cValue := oResult:MyField
   cValue := oResult:mYfIELD

   ...will both work equally well.

New features:

   o Added myPGSQLBrowse
     This is a modified version of myBrowse.  Simply do the following:

     - instantiate and :create() the browse in the usual way
     - call :setup(oRes) where oRes is an instance of the PGResult()
       class.
     - add columns and go.

     There is an example of using this in the sample code.

   o Added the following methods:
     :position()     // analagous to dbPosition()
     :goToPosition() // dbGoToPosition()
     :recno()        // returns current tuple #

   o Tightened code in :goTo() to correctly set eof/bof flags

   o Modified sample app to load queries from disk.
     If these queries contain comments (using &amp;quot;/**/&amp;quot;, not &amp;quot;--&amp;quot;), then
     the comment is displayed before the query is fired.

     The command-line for the sample app is now:

       PSQLTEST &amp;lt;queryFile&amp;gt; &amp;lt;databaseName&amp;gt; &amp;lt;userName&amp;gt; &amp;lt;passWord&amp;gt;

     I save my queries in files named *.sql - you can use anything you
     like.

   o Added High-Resolution Timer to sample app to show how long it takes
     to fire a query and receive the result.  If you don't want this,
     then comment out or remove the offending lines of code, and
     remove HRTimer.prg from the project file.

   o Since the uuid.lib problem is resolved, the pre-compiled DLL and
     LIB are no longer included in the package.

=====================
v0.2

This adds new functionality not specific to PostgreSQL/LibPQ.

The PGResult() class has new features.

  o Automatically tracks which tuple (row) you are on.

  o added methods for:
    :skip([&amp;lt;n&amp;gt;])
    :goTop()
    :goBottom()
    :eof()         // test EOF
    :bof()         // test BOF
    :goTo(&amp;lt;n&amp;gt;)     // jump to tuple (returns new row if success else
                   // current row)


  o Dynamically handles field names.  If the result returns a column
    named &amp;quot;MyField&amp;quot;, then you can retrieve the value of the field by
    doing this:

      cValue := oResult:MyField

    I'm not sure whether case-sensitivity is involved here.
    If you specify a field that doesn't exist, a runtime error will be
    raised.

  o You can retrieve the list of column names:
    :getFieldNames() -&amp;gt; aFieldNames

  o properties (iVars) exposed in PGResult() are:
    :resID    READONLY // result ID returned by the server
    :curTuple READONLY // current row of data set
    :connID            // PgSQL() object managing connection for this
                       // result
    :rows              // number of rows in result
    :cols              // number of columns in result
    
    There is also a :message property - DO NOT mess with it!


Regards,&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/69/attachments/0/xbpgsql.zip" length="39497" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/69</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/70/XbPCre.html</guid><title>XbPCre</title><pubDate>Fri, 9 May 2008 11:03:19 +0200</pubDate><link>http://news.xb2.net/xfree.resources/70/XbPCre.html</link><comments>http://news.xb2.net/xfree.resources/70/XbPCre.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR) and Hector Pezoa
--------------------------------------------------------------------
 Author : Phil Ide           
 Created: 30/05/2003         
--------------------------------------------------------------------
XbPCRE - PCRE (Perl Compatible Regular Expression) Library for Xbase++

a) Version info
1. Description
2. Package Contents
3. Requirements
4. Author's Notes
==================================================================
a) v1.2
This version is a revamp of the code to break the regexp class into
two classes - a base-class to handle PCRE comms, and a descendant
class which contains the Xbase++ API.

It also includes a newer version of PCRE.DLL which has better memory
management, and some changes to the code (supplied by
Evgeny Bogolyubov) which take advantage of this.

Additionally, the calling templates for calling the PCRE functions are
precompiled as CLASS iVars.  This results in a (very small) delay in
generating the first instance of the RegExp() class, but will result
in a slightly faster incrase in performance since no testing needs to be
done to see whether the template has already been compiled.

My thanks to Evgeny for finding, isolating and curing the memory
problem.  Evgeny found that memory was leaking away when performing vast
numbers of regex matches across thousands of files in a short loop.
Most of us don't need to do that, and so wouldn't have noticed, but
thanks to his vigilance we now have a more stable version.

WARNING: XbPCRE.DLL should be replaced entirely by this version.
         PCRE.DLL is updated - the new XbPCRE.DLL *REQUIRES* the new
         version!

         Compiled with Xbase++ v1.81 - you must recompile if using
         1.82 or later!
         
----
v1.1

This version fixes a couple of bugs:
  o - oReg:result() (no parameter)returned an error
      this was due to an incorrect algorithm which
      derived the result data
  o - DLLFUNCTION calls ran out of handles in intensive
      usage situations!

As a result of the fix to the second bug above, XbPCRE is now
faster by a factor of several hundred times, most noticeable in
intensive usage situations.

==================================================================

1. Description
--------------
This library provides an Xbase++ wrapper for PCRE.

==================================================================
2. Package Contents
-------------------
Included in this package is:

Book\
   XbPCRE.hlp
   XbPCRE.cnt        - help files
Include\
   xbpcre.ch         - #defines for use with XbPCRE
Lib\
   XbPCRE.DLL
   XbPCRE.LIB        - both compiled with Xbase++ 1.80.284
   PCRE.DLL          - Win32 DLL port of PCRE
   Source\
      XbPCRE\
         regexp.prg
         project.xpj - XbPCRE library source and project file
Pcre\
   Docs\
      Licence.txt    - PCRE usage/distribution licence
      pcre.html      - PCRE docs in HTML format
      pcre-man.pfd   - PCRE docs in PDF format
      pcre.txt       - PCRE docs in text format
      Tech.Notes     - PCRE technical notes in text format
Source\
   Samples\
      XbPCRE\
         *.*         - Example/Test project and data files

==================================================================
3. Requirements:
-------------
Xbase++ (duh!)


==================================================================
4. Author's Notes
-----------------

The PCRE documentation is provided for those who require it, but the
help file contains all the sections describing regex syntax cribbed from
the PCRE docs.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/70/attachments/0/xbpcre.zip" length="315287" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/70</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/71/XbZLib+-+Andreas+Gehrs-Pahl.html</guid><title>XbZLib - Andreas Gehrs-Pahl</title><pubDate>Fri, 9 May 2008 11:06:58 +0200</pubDate><link>http://news.xb2.net/xfree.resources/71/XbZLib+-+Andreas+Gehrs-Pahl.html</link><comments>http://news.xb2.net/xfree.resources/71/XbZLib+-+Andreas+Gehrs-Pahl.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;&lt;/pre&gt;</description><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/71</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/72/XbZLib+Build+1.40.098.html</guid><title>XbZLib Build 1.40.098</title><pubDate>Fri, 9 May 2008 11:12:23 +0200</pubDate><link>http://news.xb2.net/xfree.resources/72/XbZLib+Build+1.40.098.html</link><comments>http://news.xb2.net/xfree.resources/72/XbZLib+Build+1.40.098.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;XbZLib Build 1.40.098
-------------------------------------------------------------------------------------------------------------------------------
Downloaded from the Andreas web site
 http://www.DDPSoftware.com/XbZLib14.zip
-------------------------------------------------------------------------------------------------------------------------------
Original 'XbZLib' wrapper library for 'ZLib': 
Copyright  2003-2005 Phil Ide. 

Implementation of the extended XbZLibZip Class, based on Phil's original 'XbZLib' wrapper library for 'ZLib', as well as this Help File: 
Copyright  2004-2005 Andreas Gehrs-Pahl. 
-------------------------------------------------------------------------------------------------------------------------------&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/72/attachments/0/XbZLib14.zip" length="1186707" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/72</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/73/xb2net.chm.html</guid><title>xb2net.chm</title><pubDate>Fri, 9 May 2008 19:29:43 +0200</pubDate><link>http://news.xb2.net/xfree.resources/73/xb2net.chm.html</link><comments>http://news.xb2.net/xfree.resources/73/xb2net.chm.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Hi,

Just added the  table of contents and a index to the original xb2net 3.2.00 manual from Boris
and compiled as a CHM.

Hope you will found it usefull.

Regards,
Pablo Botella&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/73/attachments/0/xb2net_chm.zip" length="133110" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/73</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/74/BmpMenu.html</guid><title>BmpMenu</title><pubDate>Sun, 11 May 2008 10:18:52 -0600</pubDate><link>http://news.xb2.net/xfree.resources/74/BmpMenu.html</link><comments>http://news.xb2.net/xfree.resources/74/BmpMenu.html</comments><author>ramirezosvaldo@yahoo.com</author><description>&lt;pre&gt;Rescued by: Jimmy ( AUGE_OHR)
--------------------------------------------------------------------

Author:
Phil Ide
phil@idep.org.uk

Credits:
This work is built upon a sample presentation submitted by Paolo
Visenti of another developers work - who's name has been lost in the
mists of time.

All I have done is encapsulate this work in such a manner as
it becomes as transparent and versatile to use as possible.

===============================================================
1.  Purpose
2.  General Usage
3.  Extra functionality
===============================================================

1.  Purpose
     Dynamically add bitmaps icon-fashion to the left of menu
     items.

     There is a bit of bonus flexibility built-in, but it's
     usage is deliberately limited.
===============================================================

2.  General Usage
     Use (almost) as normal!

     a. Add two #define's to the source file where you create your
        menu and dialog window:

             #define XbpDialog BmpMenuDialog
             #define XbpMenu piBMPMenu

     b. Get the menubar object from the window via oDlg:MenuBar().
     c. Construct your menu's as normal.
     d. When adding items to submenu's, add the resource id of
        the required bitmap as an extra (optional) parameter:

             oSubMenu:addItem( aItem , BMP_FILE_RESOURCE_ID )

     e. Add piBMPMenuBar.prg to your project makefile.

     That's it.

     Splitbars are handled automatically, and items without
     icons in submenu's where other items have icons are also
     handled transparently, as are submenu's without icons.
===============================================================

3.  Extra functionality

     oSubMenu:getBMP( nPos )
         Returns the resource ID associated with the item at the
         ordinal position identified by nPos.  ID's less than 1
         indicate no resource associated with this item.

     oSubMenu:setBMP( nPos, xID )
         Sets/changes the resource ID for a given item. xID can be
         one of the following:
             nID1
             {nID1}
             {nID1,nID2}

         The method will normalise the parameter to a two
         element array, given either a single element array or a
         simple numeric.  If forced to populate the second element
         itself, it will duplicate the value in the first element.

     NOTE: :setBMP() should NOT be used after the window (and
           hence the menu) has been :show()'n.  It won't hurt, but
           it will have no effect.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/74/attachments/0/bmpmenu.zip" length="6973" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/74</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/75/Splash+Screen.html</guid><title>Splash Screen</title><pubDate>Fri, 16 May 2008 09:44:41 -0600</pubDate><link>http://news.xb2.net/xfree.resources/75/Splash+Screen.html</link><comments>http://news.xb2.net/xfree.resources/75/Splash+Screen.html</comments><author>ramirezosvaldo@yahoo.com</author><description>&lt;pre&gt;Rescue by Donald R. Keating

Thanks a lot


Splash.exe
(c) Phil Ide 2002, All Rights Reserved

e-mail: phil@idep.org.uk
http://www.idep.org.uk/xbase/

---------------------------------------------------
Usage: splash &amp;lt;appExe&amp;gt;;&amp;lt;appWinTitle&amp;gt;

&amp;lt;appExe&amp;gt; is the full name of the executable file, including any path
as appropriate.

&amp;lt;appWinTitle&amp;gt; is the text that appears on your applications title bar.
This is used both as a message to display on the loaders dialog, and
as a search expression when looking to see when if the window has
appeared. This is case sensitive, and preserving spaces is also
important.

The two parameters must be unquoted, and are seperated by a semi-colon
without additional spaces.

Examples:
   splash faqce.exe;Xbase++ FAQ Client Engine
   splash waa1srv.exe;Alaska Web Application Adaptor Version 1.70

Note that in version 1.8, WAA has an additional space in the title:
   splash waa1srv.exe;Alaska Web Application Adaptor Version  1.80

There is very little in the way of error checking in the code. It relies
on you being able to supply the correct arguments. If the named
application fails to load or cannot be found, you can kill the
launcher with the mouse, ALT-F4 etc. If no parameters are supplied, a
default message suggesting you read the docs is displayed.

---------------------------------------------------
This version (obviously) does not require recompiling in order to launch
any given application, which makes it a lot easier for those who are
unfamiliar with C++ to use. Additionally, it means the same
application can be used to launch multiple programs.

Here's an example of my WAA startup batch file, which relies on the
launcher to be on the path:

SET WAA_WORKERTHREADS=5
SET WAA_HOST=localhost
SET WAA_PORT=1024
SET WAA_TRACE=OFF
SET WAA_DEVMODE=OFF
copy waa1*.log logs\.
start splash.exe waa1srv.exe;Alaska Web Application Adaptor Version 1.70

If you wish to tinker with the code, you will need a 32-bit C++ compiler.
I use the Borland C++ compiler that can be downloaded free of charge from
http://www.borland.com/

---------------------------------------------------
Purpose:

This program when launched will load very quickly,
create and display a message window then launch an Xbase++
application. It will then query Windows for your Xbase++
application's main window.  As soon as it sees this,
it will kill itself, leaving focus on the Xbase++
application.

Please note that C++ is not my language of choice.
I know enough C- to muddle through, but C++ itself
is even more arcane than the wizards who live on
Planet-C would believe.  So, if you think you can
do better, or optimise this code, or make it more
flexible etc., please be my guest.  All I ask is that
you make the source freely available and that you send
me a copy of the source (including .mak, .def and any .res
files needed to create it).

I've optimised the code for readability, and ensured that the
program can both test for the existance of your secondary
application's window and still handle it's own messages (close,
resize etc.) simultaneously.&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/75/attachments/0/Splash3ByPhilIde.zip" length="130790" type="application/octet-stream" /><enclosure url="http://news.xb2.net/xfree.resources/75/attachments/1/SplashScreenByPhilIde.zip" length="29652" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/75</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/76/XmlParse.html</guid><title>XmlParse</title><pubDate>Fri, 16 May 2008 09:48:11 -0600</pubDate><link>http://news.xb2.net/xfree.resources/76/XmlParse.html</link><comments>http://news.xb2.net/xfree.resources/76/XmlParse.html</comments><author>ramirezosvaldo@yahoo.com</author><description>&lt;pre&gt;Rescue by Donald R. Keating

Thanks Don


Xml v3.0
Copyright Phil Ide 2004, All Rights Reserved

My original XML parser had numerous problems, because the code wasn't
able to do some things very well.  It became pretty complex in an
attempt to cope with some of the complexities of XML (the complexities
arise from exceptions to standard format &amp;lt;name [attrib=value]&amp;gt;dat&amp;lt;/name&amp;gt;
format).

The second parser resolved most of those issues by using regular
expressions to chop the document.  It was found though, that certain
constructs would defeat the parser.

This parser is different.  It uses well defined and tested techniques
for parsing, and represents a heavily bastardised and rationalised
version of a parser I am working on for a compiler.

It works by using a lexical parser to break the document down into
atomic and sub-atomic units, and a lexical analyser/semantic analyser to
decide how decomposition should proceed.  The back-end of the compiler
has been replaced by an Xbase++ class generator.

Written entirely in pure Xbase++, it shows how properly implemented
parsers can be used to parse a wide variety of files.  In this case,
an XML file can be parsed quickly and efficiently.  Using similar
techniques, you could also parse:

    Rich-Text Format
    MS-Word documents
    HTML
    CSV
    SDF
    SQL (command)

The BNF for the language the parser handles is:

   id      -&amp;gt; [a-zA-Z]+ALPHANUM
   value   -&amp;gt; ANY_PRINTABLE_CHARACTER
   data    -&amp;gt; ANY_PRINTABLE_CHARACTER
   attrib  -&amp;gt; id=&amp;quot;value&amp;quot;
   declare -&amp;gt; &amp;lt;?xml [attrib]* ?&amp;gt;
   expr    -&amp;gt; &amp;lt;id [attrib]*&amp;gt;[expr|data]*&amp;lt;/id&amp;gt;
            | &amp;lt;id [attrib]* /&amp;gt;
            | &amp;lt;!id [attrib]*&amp;gt;
            | declare

I make no apology that the code doesn't follow a more formal
construction - I took an existing parser and hacked it down, then added
sufficient code as and where necessary to interpret the input stream
properly.  If I was starting from scratch, I may well have done a better
job of seperating the lexical analyser from the semantic analyser, or
brought the two together into a single unit in a much neater fashion.

Regardless, the parser appears to work on a wide variety of sample
documents, many of which were selected because they had defeated the
previous incarnations of the XML parser.  It is blazingly fast,
despite the fact that it reads the input stream one byte at a time, which
is a testament to Xbase++'s ability more than the code.  I have
attempted to optimise the code where I could, using my high-resolution
timer to nip-out millionths of a second where appropriate (since the
code runs in loops and recursions, such optimisation quickly pays
dividends).

-------------------------------------------------------------
Usage:

The Parser is incorporated in a class, which makes it thread-safe.
Since the parser is no longer needed once the document has been
decomposed, the DOM is implemented as a seperate class.  The parser
generates instances of the XML() class as required, and returns the
topmost object in the DOM tree.  This allows the parser to be
discarded once processing a document has been completed.

At the top of the source file is this construct:

#ifdef _TEST_
    Function Main(cFile)
       local oXml
       local nH
       if FExists(cFile)
          oXml := ParseXml( memoread(cFile) )
          if !oXml == NIL
             nH := FCreate('test.xml')
             FWrite(nH,oXml:asString())
             FClose(nH)
          endif
       endif
       return nil
#endif

You can compile the source as a stand-alone executable with this command
line:

xpp xmlparser /m /n /w /a /b /d_TEST_ /link:&amp;quot;/de&amp;quot;

The function ParseXml() accepts an input stream representing an XML
document - in the above code, this is implemented by reading the
document into memory via the MemoRead() function.  The return value of
this function is the top-level object in the heirarchy, which should
always be named '?xml'.

The methods exposed by the XML class are:

init
asString
compose
parent
children
getChild
allSiblings
siblings
getSibling
getPreviousSibling
getNextSibling
isOrphan
getAttribute
setAttribute
findAttribute
findChildFromName
findChildFromAttribute
findAllChildrenFromName
findSiblingFromName
findSiblingFromAttribute&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/76/attachments/0/xmlParser3ByPhilIde.zip" length="67504" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/76</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/78/HB_RMChart+-+Hubert+Brandel.html</guid><title>HB_RMChart - Hubert Brandel</title><pubDate>Wed, 21 May 2008 17:24:00 +0200</pubDate><link>http://news.xb2.net/xfree.resources/78/HB_RMChart+-+Hubert+Brandel.html</link><comments>http://news.xb2.net/xfree.resources/78/HB_RMChart+-+Hubert+Brandel.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;Many thanks to Hubert Brandel for this contribution
Xbase++ wrapper over RMChart.dll

Also a big thank you to Rainer Morgen for this great library.

Hubert's Home Page
German  - www.familie-brandel.de/index.htm
English - www.familie-brandel.de/index_e.htm

RMChart Home page
http://www.rmchart.com/&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/78/attachments/0/HB_RMChart_1.00.zip" length="1068249" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/78</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/80/ot4xb+-+Build%3a+1_5_1_42.html</guid><title>ot4xb - Build: 1_5_1_42</title><pubDate>Wed, 21 May 2008 12:55:47 +0200</pubDate><link>http://news.xb2.net/xfree.resources/80/ot4xb+-+Build%3a+1_5_1_42.html</link><comments>http://news.xb2.net/xfree.resources/80/ot4xb+-+Build%3a+1_5_1_42.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;ot4xb - Build: 1_5_1_42&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/80/attachments/0/ot4xb.zip" length="175017" type="application/octet-stream" /><enclosure url="http://news.xb2.net/xfree.resources/80/attachments/1/TestXbp19Subclass.zip" length="1292" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/80</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/82/ot4xb+-+Build%3a+1_5_1_29.html</guid><title>ot4xb - Build: 1_5_1_29</title><pubDate>Wed, 7 May 2008 11:05:51 +0200</pubDate><link>http://news.xb2.net/xfree.resources/82/ot4xb+-+Build%3a+1_5_1_29.html</link><comments>http://news.xb2.net/xfree.resources/82/ot4xb+-+Build%3a+1_5_1_29.html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;ot4xb - Build: 1_5_1_29&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/82/attachments/0/ot4xb.zip" length="174521" type="application/octet-stream" /><enclosure url="http://news.xb2.net/xfree.resources/82/attachments/1/ot4xb_src.zip" length="146359" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/82</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/84/Re%3a+Comenzando+con+PG....html</guid><title>Re: Comenzando con PG...</title><pubDate>Fri, 6 Jun 2008 09:48:38 +0200</pubDate><link>http://news.xb2.net/xfree.resources/84/Re%3a+Comenzando+con+PG....html</link><comments>http://news.xb2.net/xfree.resources/84/Re%3a+Comenzando+con+PG....html</comments><author>pbn_NOSPAM_@pablob.com</author><description>&lt;pre&gt;En el zip adjunto tienes libpq4xb.ch y  libpq4xb.prg
Aun no los hemos subido a xfree.resources porque aun falta testear un poco m&amp;#225;s y poner ejemplos
Saludos,
Pablo Botella

--------------------------------------------------------------------------------------------------------
Have attached a zip file including libpq4xb.ch and libpq4xb.prg
Still not in the xfree.resources NG becouse still needed to be tested  more and also write some examples&lt;/pre&gt;</description><enclosure url="http://news.xb2.net/xfree.resources/84/attachments/0/libpq4xb.zip" length="3691" type="application/octet-stream" /><comment xmlns="http://wellformedweb.org/CommentAPI/">http://news.xb2.net/comment.api/xfree.resources/84</comment></item><item><guid isPermaLink="true">http://news.xb2.net/xfree.resources/85/Re%3a+ot4xb+-+snapshots.html</guid><title>Re: ot4xb - snapshots</title><pubDate>Fri, 6 Jun 2008 14:34:44 +0200</pubDate><link>http://news.xb2.net/xfree.resources/85/Re%3a+ot4xb+-+snapshots.html</link><comments>http://news.xb2.net/xfree.resources/85/Re%3a+ot4xb+-+snapshots.html</comments><author>pb