PureBytes Links
Trading Reference Links
|
<x-html><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type>
<META content="MSHTML 5.00.2614.3500" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT size=2>Ton:</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=2>I could not open the attached file. I got a message that
it was not a gif file (using Paint Shop Pro).</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=2>Can you resend It?</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=2>Thanks</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=2>Lionel Issen</FONT></DIV>
<BLOCKQUOTE
style="BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV style="FONT: 10pt arial">----- Original Message ----- </DIV>
<DIV
style="BACKGROUND: #e4e4e4; FONT: 10pt arial; font-color: black"><B>From:</B>
A.J. Maas
</DIV>
<DIV style="FONT: 10pt arial"><B>To:</B> <A
href="mailto:metastock@xxxxxxxxxxxxx"
title=metastock@xxxxxxxxxxxxx>Metastock-List</A> </DIV>
<DIV style="FONT: 10pt arial"><B>Sent:</B> Thursday, September 16, 1999 10:13
PM</DIV>
<DIV style="FONT: 10pt arial"><B>Subject:</B> Re: Windows API</DIV>
<DIV><BR></DIV>
<DIV><FONT size=2>A re-post (previous did not make it to the
List).</FONT></DIV>
<DIV><BR>Regards,<BR>Ton Maas<BR><A
href="mailto:ms-irb@xxxxxxxxxxxxxxxx">ms-irb@xxxxxxxxxxxxxxxx</A><BR>Dismiss
the ".nospam" bit (including the dot) when replying and<BR>note the new
address change. Also for my Homepage<BR><A
href="http://home.planet.nl/~anthmaas">http://home.planet.nl/~anthmaas</A></DIV>
<DIV> </DIV>
<DIV> </DIV>
<BLOCKQUOTE
style="BORDER-LEFT: #000000 2px solid; MARGIN-LEFT: 5px; MARGIN-RIGHT: 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px">
<DIV style="FONT: 10pt arial">----- Original Message ----- </DIV>
<DIV
style="BACKGROUND: #e4e4e4; FONT: 10pt arial; font-color: black"><B>From:</B> A.J.
Maas </DIV>
<DIV style="FONT: 10pt arial"><B>To:</B> <A
href="mailto:metastock@xxxxxxxxxxxxx"
title=metastock@xxxxxxxxxxxxx>metastock@xxxxxxxxxxxxx</A> </DIV>
<DIV style="FONT: 10pt arial"><B>Sent:</B> zaterdag 11 september 1999
19:11</DIV>
<DIV style="FONT: 10pt arial"><B>Subject:</B> Re: Windows API</DIV>
<DIV><BR></DIV>
<DIV><FONT size=2>Windows API : This below can be found @ </FONT></DIV>
<DIV><FONT size=2><A
href="http://msdn.microsoft.com/library/periodic/period96/D1/FT0296.htm">http://msdn.microsoft.com/library/periodic/period96/D1/FT0296.htm</A></FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=2>Also click the "show toc"-icon below to go to the MSDN
Library (eg a treasure for Windows developers</FONT></DIV>
<DIV><FONT size=2>and not to be mixed up with the Windows library files (eg
drivers + dll's + ocx's etc.).</FONT></DIV>
<DIV><FONT size=2> </DIV></FONT>
<DIV><FONT size=2>And naturaly there is more:</FONT></DIV>
<DIV><FONT size=2><A
href="http://search.microsoft.com/us/results.asp?SName=Developer+Sites&SPath=http://msdn.microsoft.com&SCatalog=Developer&IntCat=11&Boolean=PHRASE&Nq=TRUE&qu=WIN32API&submit1=search">http://search.microsoft.com/us/results.asp?SName=Developer+Sites&SPath=http://msdn.microsoft.com&SCatalog=Developer&IntCat=11&Boolean=PHRASE&Nq=TRUE&qu=WIN32API&submit1=search</A></FONT></DIV>
<DIV><FONT size=2>(note: the lines above were split but should be
copied+pasted in full as it is also one(1) full website's
address)</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=2>Regards,<BR>Ton Maas<BR><A
href="mailto:ms-irb@xxxxxxxxxxxxxxxx">ms-irb@xxxxxxxxxxxxxxxx</A><BR>Dismiss
the ".nospam" bit (including the dot) when replying and<BR>note the new
address change. Also for my Homepage<BR><A
href="http://home.planet.nl/~anthmaas">http://home.planet.nl/~anthmaas</A></FONT></DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV><FONT size=2>----- Original Message ----- </FONT>
<DIV><FONT size=2>From: Walter Lake</FONT></DIV>
<DIV><FONT size=2>To: Metastock bulletin board <<A
href="mailto:metastock@xxxxxxxxxxxxx">metastock@xxxxxxxxxxxxx</A>></FONT></DIV>
<DIV><FONT size=2>Sent: donderdag 9 september 1999 15:34</FONT></DIV>
<DIV><FONT size=2>Subject: Windows API</FONT></DIV></DIV>
<DIV><BR></DIV>
<DIV><FONT size=2>> Thanks for your email. Sorry but I don't know how to
do that.<BR>> <BR>> There is a whole section of advanced Excel VBA
programming using Windows API<BR>> (Application Programming Interface)
that is covered in the WROX programmers<BR>> reference book. Usually,
that kind of access to the Windows platform and<BR>> ".dll's" is used by
C and C+ programmers.<BR>> <BR>> Where Windows API programming is of
interest is when you want to take over<BR>> the entire Excel interface
and create your own icon's etc.<BR>> <BR>> As I mentioned earlier, you
can make Excel look less and less like Excel and<BR>> more like your own
program using VBA and VBA access to Windows API.<BR>> <BR>> Using
Windows API, as far as I know, is not only complicated but "risky"<BR>>
because of the lack of error messages and difficulty figuring out what
went<BR>> wrong when things don't work correctly.<BR>> <BR>>
Personally, I'm going to leave all of that to the C and C+
programmers.<BR>> "Plain" VBA is complicated enough for an untrained and
"clueless" programmer<BR>> such as myself.<BR>> <BR>> Maybe Guy or
Ton can post some general info about Windows API and the MSDN<BR>>
library files.<BR>> <BR>> There's suppose to be a "win32api.txt" file
that has all of the declarations<BR>> for the core windows functions
written in VBA notation. I don't know where<BR>> it is or how to find it.
Maybe Guy uses it in his programming.<BR>> <BR>> Best regards<BR>>
<BR>> Walter<BR>> <BR><!--TOOLBAR_START--><!--TOOLBAR_EXEMPT--><!--TOOLBAR_END--><!--SYNC_START-->
<SCRIPT language=JavaScript src="/library/synch.js"></SCRIPT>
</FONT></DIV>
<DIV><FONT size=2> <A
href="http://msdn.microsoft.com/isapi/msdnlib.idc?theURL=/library/periodic/period96/d1/ft0296.htm"
target=_top><IMG border=0 height=17
src="mhtml:mid://00000220/!http://msdn.microsoft.com/library/images/msdn/art/mlibfram.gif"
width=75></A> <!--SYNC_END--></DIV>
<P><FONT face="Verdana, Arial, Helvetica" size=2>
<H1>Use the Windows API to Print to Multiple Print Queues</H1>
<P>Richard Aman</P>
<P><I>Richard Aman is director of software engineering at Loren Industries,
a jewelry manufacturing company with headquarters in Hollywood, Florida.
Richard has been developing business solutions in FoxBASE/FoxPro since 1988
and regularly gives presentations at his local Fox User Group. CompuServe
73700,141.</I></P>
<P>This article originally appeared in the February 1996 issue of FoxTalk,
published by Pinnacle Publishing Inc., PO Box 888, Kent, WA 98035-0888;
800-788-1900; 206-251-1900; http://www.pinpub.com.</P>
<P>Windows provides a wealth of services for controlling network
connections. Richard Aman shows how to use these services in either FoxPro
2.x or Visual FoxPro to easily send a report to any available output device.
In the process, you'll learn about Visual FoxPro's new variant of DECLARE,
which allows you to call external DLL routines as if they were native UDFs.
You'll also learn how to use several useful Windows API routines.</P>
<P>ONE of the more difficult application types I've implemented is an
automatic scheduler. A scheduler performs procedures at various scheduled
and unscheduled times throughout the day. The procedures must perform in
unattended mode and make decisions without user input. Along with
software-related decisions like branching and looping, the procedures must
make hardware decisions. For example, the software must decide which printer
to send output to, which network connection to use, when to reset the
software, and which users are logged on when.</P>
<P>When I implemented the scheduler in Windows, the main design decision was
how to allow the system to use different printers in different locations for
the various output reports—key in an order-entry and work progress-based
system like this one. I designed the system to make decisions based on
orders entered, and by the various stages of manufacture that pieces have
achieved.</P>
<H2>The Win.INI route</H2>
<P>To choose an output printer, I initially used sample code from the
Microsoft Developer's Network (MSDN) CD. That sample code had multiple
printers installed in Windows, then modified the WIN.INI file to change the
default printer. The method worked fine, although it had limitations. First,
it required that all printers to be used be installed in Windows—a problem
if you want to use the application on different machines. The second
limitation was that Windows has only a limited number of printer ports.
Though it's possible to have several printers assigned to the same port,
keeping track of them can get messy. The third limitation is that it takes
time to modify WIN.INI and notify running applications to update themselves
with the changes.</P>
<P>The method detailed on the MSDN CD used the Windows API functions
GetProfileString() and PutProfileString() to access WIN.INI. This made me
wonder what other functions for switching printers might be buried in the
Windows API. I started looking through the Microsoft Developer's Network CD
and the TechNet CD (both excellent resources) and the Windows API help file
that comes with Visual FoxPro Professional Edition for other approaches to
this problem.</P>
<H2>A better way</H2>
<P>That's when I came across the WNetGetConnection(), WNetAddConnection(),
and WNetCancelConnection() functions. These three Windows API functions
combine to give you almost unlimited programmatic control over the network
connections through an application. WNetGetConnection() returns the name of
the network connection that a local device is mapped to, or NULL if the
device isn't mapped on the network. WNetAddConnection() maps a local device
to a network connection if it's not already connected. And
WNetCancelConnection() disconnects a local device from a network connection.
With these three functions, I implemented multiple printer output through
LPT1 alone. I also found two other useful Windows API functions:
WNetGetUser(), which returns the user network login ID, and ExitWindows(),
which can be used to restart Windows from within FoxPro.</P>
<P>My automatic scheduler application scans the orders table at a recurring
interval for any new orders. When new orders are found, they're copied to
separate temporary tables for printing. Based on the type, orders can print
at one of three places in the plant. The print routine is passed through
three parameters, which tell the routine the name of the temporary table,
the report form to use, and where to send output. When the routine processes
the print location decision, it calls WNetGetConnection() to check whether
LPT1 is connected to a network print queue. If a current connection exists,
it calls WNetCancelConnection() to disconnect LPT1 from the current network
print queue. It then calls WNetAddConnection() to connect LPT1 to the proper
network print queue. (To prevent a connection error, you'll need to cancel
the existing connection before creating a new connection..)</P>
<H2>The basics</H2>
<P>Before I get to my sample code, I want to quickly cover some basic
requirements for using this method of printer control and for using any of
the Windows API functions (or functions in any Windows DLL).</P>
<P>If you're using FoxPro 2.6 for Windows, first load in the library file
FoxTools.fll, (supplied with FoxPro 2.6). This library file loads with the
command SET LIBRARY TO FoxTools. Once the library is loaded, your program
has access to a pair of functions called RegFn() and CallFn(). RegFn() is
used to register Windows API functions to FoxPro. CallFn() is used to call
the functions previously registered with RegFn(). In Visual FoxPro 3.0, the
DECLARE command replaces the need for FoxTools.fll and the RegFn() and
CallFn() routines . This new DECLARE command is also used to register
Windows API functions. Once the functions have been registered, they're
called just like the internal FoxPro functions. However, for backward
compatibility, FoxTools.fll, RegFn() and CallFn() can still be used in
FoxPro 3.0. (Refer to the Visual FoxPro 3.0 help file for more information
on the DECLARE command.)</P>
<P>If you're working in FoxPro 2.x and are new to FoxTools/RegFn/CallFn, you
can get details from "Use Microsoft Windows Services from FoxPro" by Robert
W. Lord (<I>FoxTalk</I>, March 1994). Back issues can be ordered at
800-788-1900. In the meantime, here's a brief rundown of these commands and
the new Visual FoxPro replacements for them:</P>
<H3>Loading the FoxTools.fll library</H3>
<P>First, load the FoxTools.fll library for FoxPro 2.6:</P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> SET LIBRARY TO SYS(2004) + 'FoxTools.fll' ADDITIVE</FONT></CODE></PRE>
<P>This command line uses the FoxPro function SYS(2004) to get FoxPro's home
directory, which is where FoxTools.fll is installed during normal
installation. Also, use the ADDITIVE clause to add the library to any
existing loaded libraries; otherwise, FoxTools.fll will replace any existing
loaded libraries.</P>
<H3>Using RegFn()</H3>
<P>The FoxTools function RegFn() registers a Windows API function with
FoxPro. RegFn() takes three required parameters and one optional parameter.
The first parameter is the name of the Windows API function you want to
register. The second parameter is a string containing letter designations
for the types of parameters the Windows API function requires ( 'C' for
character or string, 'I' for integer, and so forth). The third parameter is
a letter designation for the type of value the Windows API function will
return to FoxPro. The fourth and optional parameter is the name of the
Windows DLL that contains the function you want to register. If you don't
include the DLL name, FoxPro automatically looks in the standard Windows
libraries (USER.EXE, KRNL386.EXE, and GDI.EXE in Windows 3.x) to try to find
the Windows API function. If the function isn't found, an error code is
returned. If the function is successfully registered, a function handle is
returned. That handle is then used by CallFn() to access the Windows API
function, as I describe later.</P>
<H3>Using CallFn()</H3>
<P>The FoxTools function CallFn() is used to access a Windows API function
from within FoxPro once it has been registered with RegFn(). The parameters
passed to CallFn() are the Windows API function handle returned by RegFn(),
and the parameters specified in the second parameter in RegFn() when the
Windows API function was registered. </P>
<H3>Using DECLARE in Visual FoxPro</H3>
<P>DECLARE is an enhanced command in Visual FoxPro 3.0. In addition to
defining arrays, the DECLARE command also removes the need for using
FoxTools to access the Windows API functions. DECLARE allows the application
to directly register Windows API functions with FoxPro. Once the functions
are registered, they can be called like any other FoxPro internal function.
The first parameter to the DECLARE command is the Windows API function
return type. The second parameter is the name of the function you're
registering. The third parameter is the DLL containing the Windows API
function. The remainder of the parameters are the parameter types that
FoxPro will pass to the Windows API function.</P>
<H2>The Windows API functions</H2>
<H3>WNetGetConnection()</H3>
<P>WNetGetConnection() is used to retrieve the network connection to which a
local device is mapped. The first parameter is a variable containing the
name of the local device you want to check. The second parameter is a
variable initialized to spaces ( I use 255 ) and will be supplied with the
connection name by WNetGetConnection(). The last parameter is a variable
containing the length of the second parameter ( in this case 255 ). All
three parameters need to be passed by reference. After initializing the
variables, register the function with FoxPro. This lets FoxPro know that the
function will be passed three parameters by reference, two strings and one
integer, and the function will return an integer. Ensure the second
parameter buffer is empty before calling this function, because an error
won't clear the buffer and you might get incorrect results.</P>
<P>Here's the syntax for setting up the WNetGetConnection call, first for
FoxPro 2.x, then for Visual FoxPro:</P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> * FoxPro 2.x
lnGetConn = RegFn('WNetGetConnection','@C@x@I','I')
* Visual FoxPro
DECLARE INTEGER WNetGetConnection IN win32api ;
STRING @, STRING @, INTEGER @</FONT></CODE></PRE>
<P>Call the function to return the current connection for the specified
device:</P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> * FoxPro 2.x
lnRetVal = CallFn(lnGetConn, @lcDeviceName, ;
@lcConnName, @lnBuffLen)
* Visual FoxPro
lnRetVal = WNetGetConnection(@lcDeviceName, ;
@lcConnName, @lnBuffLen)</FONT></CODE></PRE>
<P>After the call to WNetGetConnection(), the buffer lcConnName will either
contain the name of the network connection for the specified local device or
will be empty if no connection currently exists for the local device. It
will also be empty if an error occurred. Also, be sure to check the return
value for any error codes. The Windows API return codes for
WNetGetConnection() follow, as found in the Windows SDK:</P>
<P>0 The function was successful.</P>
<P>8 The system was out of memory.</P>
<P>50 The function was not supported.</P>
<P>59 An error occurred on the network.</P>
<P>87 The local device name parameter was not a valid local device.</P>
<P>234 The buffer was too small. ( The connection name is longer than </P>
<P>the allotted buffer length. )</P>
<P>487 The pointer was invalid.</P>
<P>2250 The local device name parameter was not a redirected local </P>
<P>device.</P>
<H3>WNetAddConnection()</H3>
<P>WNetAddConnection() is used to map a local device to a network
connection. The first parameter is the network connection to map the device
to. The second parameter is the password to use and should be a null string
to use the default password. Finally, the third parameter is the local
device to map. After initializing the variables, register the function with
FoxPro. This lets FoxPro know that the function will be passed three
parameters as strings, and will return one integer:</P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> * FoxPro 2.6
lnAddConn = RegFn('WNetAddConnection','CCC','I')
* Visual FoxPro
DECLARE INTEGER WNetAddConnection IN win32api ;
STRING, STRING, STRING</FONT></CODE></PRE>
<P>Call the function to map the local device to the network connection:</P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> * FoxPro 2.x
lnRetVal = CallFn(lnAddConn,'\\SERVER1\HP4','','LPT1:')
* Visual FoxPro
lnRetVal = WNetAddConnection('\\SERVER1\HP4','','LPT1:')</FONT></CODE></PRE>
<P>This function returns 0 if successful, or an error number for any error
that occurs while attempting to create the network connection. I've listed
the Windows API return codes for WNetAddConnection(), which follow, as found
in the Windows SDK.</P>
<TABLE border=0 cols=2>
<COLGROUP>
<COL vAlign=top width=68>
<COL vAlign=top width=226></COLGROUP>
<TBODY>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>0</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
function was successful.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>5</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>A
security violation occurred.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>8</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
system was out of memory.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>50</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
function was not supported.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>59</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>An error
occurred on the network.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>67</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
network resource name was invalid.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>85</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The local
device was already connected to a remote resource.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>86</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
password was invalid.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>487</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
pointer was invalid.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>1200</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The local
device name was invalid.</FONT></TD></TR></TBODY></TABLE>
<P><BR></P>
<H3>WNetCancelConnection()</H3>
<P>WNetCancelConnection() is used to remove a network connection mapping
from a local device. This is necessary because the WNetAddConnection()
function will return an error if the device that you are trying to map is
already mapped to a network connection. For this reason, I recommend
checking the network mapping for the local device before attempting to
create a new connection. Also, I recommend releasing any network mapping
that exists first. The first parameter is the local device to cancel the
network connection to. The second parameter tells Windows whether to close
any open files, or simply to return an error. The second parameter should be
0 to close open files before disconnecting. After initializing the
variables, register the function with FoxPro. This lets FoxPro know that the
function will be passed two parameters, one string and one integer, and will
return one integer.</P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> * FoxPro 2.6
lnCancelConn = RegFn('WNetCancelConnection','CI','I')
* Visual FoxPro
DECLARE INTEGER WNetCancelConnection IN win32api ;
STRING, INTEGER</FONT></CODE></PRE>
<P>Call the function to cancel the connection for the specified local
device:</P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> * FoxPro 2.6
lnRetVal = CallFn(lnCancelConn,'LPT1:',0)
* Visual FoxPro
lnRetVal = WNetCancelConnection('LPT1:',0)</FONT></CODE></PRE>
<P>This function returns 0 if successful, or it returns an error number for
any error that occurs while attempting to cancel the network connection.
Following are the Windows API return codes for WNetCancelConnection(), as
found in the Windows SDK:</P>
<TABLE border=0 cols=2>
<COLGROUP>
<COL vAlign=top width=72>
<COL vAlign=top width=243></COLGROUP>
<TBODY>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>0</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
function was successful.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>8</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
system was out of memory.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>50</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
function was not supported.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>59</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>An error
occurred on the network.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>87</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The local
device name parameter was not a valid local device </FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2> </FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>or
network name. </FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>487</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
pointer was invalid.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>2250</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The local
device name parameter was not a redirected local </FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2> </FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>device or
currently accessed network resource.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>2401</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>Files
were open and the fForce parameter was 0. </FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2> </FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
connection was not canceled.</FONT></TD></TR></TBODY></TABLE>
<P><BR></P>
<H3>WNetGetUser()</H3>
<P>WNetGetUser() is used to return the network login ID of the machine the
application is running on. The first parameter is a variable containing the
local name to return the network login ID for. It should be NULL for the
current machine. The second parameter is a variable initialized to spaces (I
use 255 spaces) and will be filled in by WNetGetUser() with the network
login ID. The third parameter is the length of the second parameter. All
three parameters need to be passed in by reference in order for the function
to operate correctly. After initializing the variables, register the
function with FoxPro. This lets FoxPro know that the function will be passed
two parameters by reference, one string and one integer, and the function
will return one integer. Use NULL for the first parameter to get the current
sign-on name because if the user is signed on more than once, the system
makes a random choice of which login name to return:</P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> * FoxPro 2.x
lnGetUser = RegFn('WNetGetUser','@C@x@I','I')
* Visual FoxPro
DECLARE INTEGER WNetGetUser IN win32api ;
STRING @, STRING @, INTEGER @</FONT></CODE></PRE>
<P>Call the function to get the network login ID of the machine:</P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> * FoxPro 2.x
lnRetVal = CallFn(lnGetUser,@lcUserID,@lnBuffLen)
lnRetVal = WNetGetUser(@lcUserID,@lnBuffLen)</FONT></CODE></PRE>
<P>After the call to WNetGetUser(), the buffer lcUserID will contain either
the network login ID or will be empty if the machine isn't logged in to the
network. Also, check the return value for any error codes. Following are the
Windows API return codes for WNetGetUser(), as found in the Windows SDK:</P>
<TABLE border=0 cols=2>
<COLGROUP>
<COL vAlign=top width=59>
<COL vAlign=top width=297></COLGROUP>
<TBODY>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>8</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
function could not allocate sufficient memory to </FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2> </FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>complete
its operation.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>50</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>This
function is not supported. </FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>59</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>A network
error occurred.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>234</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
buffer was too small to hold the complete user name. </FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>487</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The
pointer is invalid.</FONT></TD></TR>
<TR>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica"
size=2>2202</FONT></TD>
<TD vAlign=top><FONT face="Verdana, Arial, Helvetica" size=2>The user
is not logged in; there is no current user name.
</FONT></TD></TR></TBODY></TABLE>
<P><BR></P>
<H3>ExitWindows() and ExitWindowsEx()</H3>
<P>ExitWindows() has two uses of interest, based on the first parameter
passed in. The first parameter is a flag to tell Windows to either reboot or
exit. The second parameter is reserved and should be 0. If you pass in a 67
to the first parameter, Windows will close down any running applications and
exit to the DOS prompt. If you pass in a 66, Windows will close down any
running applications and restart Windows. (the function is called
ExitWindowsEx() in 32-bit Windows; the first parameter should be 0 to
restart Windows.) I use a 66 in the automatic scheduler application . After
initializing the variables, register the function with FoxPro. This lets
FoxPro know that the function will be passed two parameters, both integers,
and the function will return one integer:</P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> * FoxPro 2.x
lnExitWin = RegFn('ExitWindows','II','I')
* Visual FoxPro
DECLARE INTEGER ExitWindowsEx IN user32 ;
INTEGER, INTEGER</FONT></CODE></PRE>
<P>Call the function to restart Windows:</P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> * FoxPro 2.x
lnRetVal = CallFn(lnExitWin,66,0)
* Visual FoxPro
lnRetVal = ExitWindowsEx(0,0)</FONT></CODE></PRE>
<P>ExitWindows() and ExitWindowsEx() have only two return codes: 0 or FALSE
if an error occurred, and 1 or TRUE if the function call was successful. In
this use of ExitWindows() or ExitWindowsEx(), you probably need only check
for a failure return code, since a successful call would have restarted
Windows and FoxPro, meaning the return code value would have been released.
But a check for success might be important in other uses.</P>
<P>Why use ExitWindows() or ExitWindowsEx()? I use ExitWindows() because of
a "memory leak" in FoxPro for Windows 2.6, which my scheduler runs under.
When FoxPro generates a report, some of the memory used isn't released back
to the pool of free memory. Consequently, after a certain number of reports,
FoxPro can run out of memory. In my case, problems occur after approximately
75 work production tickets, each with a bitmap of the item and several
different fonts. To prevent this, I set up FoxPro in the Windows StartUp
group with a command line call to the automatic scheduler. Then, every 15
minutes I call a procedure called ResetWin (included on this month's
Companion Disk), which closes down FoxPro and restarts Windows. When Windows
starts up, it runs FoxPro from the StartUp group, which then restarts the
automatic scheduler, which picks up where it left off—but with refreshed
memory. Everything runs smoothly with this scheme in place.</P>
<P>Presumably, this memory leak has been fixed in Visual FoxPro, but you may
still want to use ExitWindowsEx() to automatically shut down or restart some
application types, perhaps at particular times of the day when demand is
minimal. It often helps to get a "clean slate" periodically for an automated
server application on a dedicated workstation, particularly if the
application has the potential of running unattended for days or weeks.</P>
<P>Listing 1 illustrates my basic method of printer control. Prior to this
procedure, the application will have selected the records to be printed, the
report form to use, and the network print queue destination, all of which
are passed in through parameters. I first initialize my variables and save
the current library setting. I then make sure the Foxtools library is loaded
for version 2.x. Next, I register the Windows API functions with FoxPro (
using the DECLARE command for version 3.0 or the RegFn() for version 2.x ).
Then I check for and release any existing connection for LPT1: using
WNetGetConnection(). I then set LPT1: to the desired network print queue
with WNetAddConnection(). After all is set up properly, I loop through the
source table and generate a full-page form for each record (this allows
other users to insert print jobs between my frequent multi-page output).
Finally, I make a call to GetNetID() to see if I'm on the automatic
scheduler. If so, I reset LPT1: to a default network print queue. I then
restore the previous library setting and exit the routine.</P>
<P>The call to the GetNetID UDF deserves a little more explanation.
GetNetID() is included on this month's Companion Disk. It calls the Windows
WNetGetUser() function to return the network login ID of the machine the
application is running on. This can be used for a variety of things. In
AutoPrnt, I check the network ID with GetNetID() to see if the application
print routine is running on the automatic scheduler machine. If so, I re-map
the printer back to the default queue so normal output that doesn't need to
be specifically redirected can be printed on the central printer. </P>
<P><B>Listing 1. The AutoPrnt procedure.</B></P>
<P><BR></P><PRE><CODE><FONT face="Verdana, Arial, Helvetica" size=2> ********************************************************
* PROCEDURE AutoPrnt
********************************************************
* Author............: Richard L. Aman
*) Description.......: A scaled down version of the print
*) : engine for the automatic scheduler
* Calling Samples...: DO AutoPrnt WITH cSrcTable,
*) : cFormName, cPrinter
* Parameter List....: cSrcTable - table containing
*) : records to print
* : cFormName - name of form to use
* : cPrinter - report destination
PROCEDURE AutoPrnt
PARAMETERS cSrcTable, cFormName, cPrinter
*-- define variables
PRIVATE lcFormName, lcPrinter, lcReport, lcOldPrinter, ;
lcOldLibrary, lnAddConn, lnDelConn, lnGetConn, ;
lcDeviceName, lcConnName, lnBuffLen, ;
llVersion3, lcConnTo, lnRetVal
*-- init variables
lcFormName = cFormName
lcPrinter = cPrinter
lcReport = lcFormName
lcOldPrinter = ''
lcOldLibrary = SET('LIBRARY')
lcDeviceName = 'LPT1'
lcConnName = SPACE(254)
lnBuffLen = LEN(lcConnName)
llVersion3 = '3.0' $ VERSION()
lcConnTo = ''
lnRetVal = 0
*--ensure that foxtools library is loaded
IF NOT llVersion3
IF NOT 'FOXTOOLS' $ UPPER( lcOldLibrary )
SET LIBRARY TO SYS( 2004 ) + 'FOXTOOLS.FLL' ADDITIVE
ENDIF
ENDIF
*-- register the Windows API functions
IF llVersion3
DECLARE INTEGER WNetAddConnection IN win32API ;
STRING, STRING, STRING
DECLARE INTEGER WNetCancelConnection IN win32API ;
STRING, INTEGER
DECLARE INTEGER WNetGetConnection IN win32API ;
STRING @, STRING @, INTEGER @
ELSE
lnAddConn = RegFn('WNetAddConnection','CCC','I')
lnDelConn = RegFn('WNetCancelConnection','CI','I')
lnGetConn = RegFn('WNetGetConnection','@C@x@I','I')
ENDIF
*-- check for an existing connection
IF llVersion3
lnRetVal = WNetGetConnection(@lcDeviceName, ;
@lcConnName,@lnBuffLen)
ELSE
lnRetVal = CallFn(lnGetConn,@lcDeviceName, ;
@lcConnName,@lnBuffLen )
ENDIF
IF NOT EMPTY( lcConnName )
IF llVersion3
lnRetVal = WinNetCancelConnection('LPT1:',0)
ELSE
lnRetVal = CallFn(lnDelConn,'LPT1:',0)
ENDIF
ENDIF
*-- set the printer to the correct queue
DO CASE
CASE lcPrinter = 'MIS'
lcConnTo = '\\SERVER1\MIS'
CASE lcPrinter = 'QC'
lcConnTo = '\\SERVER1\HP4'
CASE lcPrinter = 'PRODUCTION'
lcConnTo = '\\SERVER2\PRODPRINT'
ENDCASE
IF llVersion3
lnRetVal = WNetAddConnection( lcConnTo, '','LPT1:')
ELSE
lnRetVal = CallFn(lnAddConn,lcConnTo,'','LPT1:')
ENDIF
*-- print the report for each record
GO TOP
SCAN WHILE LASTKEY() <> 27 && allow ESC
REPORT FORM &lcReport TO PRINTER NEXT 1 NOCONSOLE
ENDSCAN
*-- clean up and return
IF GetNetID() = 'SCHEDULE'
IF llVersion3
lnRetVal = WNetCancelConnection('LPT1:',0)
lnRetVal = WNetAddConnection('\\SERVER1\PRINTQ_0',;
'','LPT1:')
ELSE
lnRetVal = CallFn(lnDelConn,'LPT1:',0)
lnRetVal = CallFn(lnAddConn,'\\SERVER1\PRINTQ_0',;
'','LPT1:')
ENDIF
ENDIF
SET LIBRARY TO &lcOldLibrary
RETURN</FONT></CODE></PRE>
<H2>Things I learned the hard way about using Windows API functions </H2>
<P>If the function declaration calls for a value to be passed by reference,
you <I>must</I> use a variable and preface it with the "@" symbol. I thought
that for the buffer length, I could set a variable with the length of the
buffer, then just pass the variable, but not in this case. I still had to
use the "@" symbol.</P>
<P>If you're using the Visual FoxPro calling convention with the DECLARE
command, the Windows API function names are case-sensitive.</P>
<P>Always remember to check the return value for any error codes.
Unfortunately, I didn't have enough space in this article to go into detail
about handling errors, but at the very least you should determine what the
function returns when it's successful and test for that. Don't forge ahead
in your code just <I>assuming</I> that the API function executed
successfully.</P>
<H2>Conclusion</H2>
<P>FoxPro for Windows and Visual FoxPro provide a rich programming language
that allows the developer to create applications of amazing power and
complexity. However, even with all the commands included, there are still
times when a task either can't be accomplished with native FoxPro code, or
the overhead associated with the procedure written in native FoxPro causes
too great a performance hit. When you hit a brick wall in your development
and FoxPro just won't cooperate, take time to browse through the Windows API
help file (included with the Professional Edition of Visual FoxPro and other
Microsoft "visual" development products). You may find just what you
need.</P>
<P>Having easy access to around 75 percent of the Windows API functions (the
rest require abstract data types such as C structures so you have to either
be very tricky or write C routines to access them), opens up a world of
possibilities for developers who do a little research. I hope these examples
help you, and let you build on what I've presented here. I look forward to
comments, questions or suggestions. </P>
<P align=center><A href="http://www.pinpub.com/foxtalk/"><IMG border=0
height=72
src="mhtml:mid://00000220/!http://msdn.microsoft.com/library/periodic/period96/D1/Pinnacle.gif"
width=216></A></P>
<P align=center><STRONG>To find out more about FoxTalk and Pinnacle
Publishing, visit their website at</STRONG> <BR><A
href="http://www.pinpub.com/foxtalk/"><STRONG>http://www.pinpub.com/foxtalk/</STRONG></A></P>
<P align=center><FONT face="Verdana, Arial, Helvetica" size=2>Note: This is
not a Microsoft Corporation website. <BR>Microsoft is not responsible for
its content.</FONT></P>
<P><I>This article is reproduced from the February 1996 issue of
</I>FoxTalk<I>. Copyright 1995, by Pinnacle Publishing, Inc., unless
otherwise noted. All rights are reserved. </I>FoxTalk<I> is an independently
produced publication of Pinnacle Publishing, Inc. No part of this article
may be used or reproduced in any fashion (except in brief quotations used in
critical articles and reviews) without prior consent of Pinnacle Publishing,
Inc. To contact Pinnacle Publishing, Inc., please call (800)788-1900 or
(206)251-1900.</I></P></FONT><A
href="http://msdn.microsoft.com/isapi/gomscom.asp?TARGET=/misc/cpyright.htm"
target=_top>© 1999 Microsoft Corporation. All rights reserved. Terms of
use</A></FONT></BLOCKQUOTE></BLOCKQUOTE></BODY></HTML>
</x-html>From ???@??? Fri Sep 17 12:21:41 1999
Return-Path: <majordom@xxxxxxxxxxxxxxxxxx>
Received: from listserv.equis.com (listserv.equis.com [204.246.137.2])
by purebytes.com (8.8.7/8.8.7) with ESMTP id MAA16997
for <neal@xxxxxxxxxxxxx>; Fri, 17 Sep 1999 12:13:36 -0700
Received: (from majordom@xxxxxxxxx)
by listserv.equis.com (8.8.7/8.8.7) id CAA26035
for metastock-outgoing; Sat, 18 Sep 1999 02:16:52 -0600
X-Authentication-Warning: listserv.equis.com: majordom set sender to owner-metastock@xxxxxxxxxxxxx using -f
Received: from freeze.metastock.com (freeze.metastock.com [204.246.137.5])
by listserv.equis.com (8.8.7/8.8.7) with ESMTP id CAA26031
for <metastock@xxxxxxxxxxxxxxxxxx>; Sat, 18 Sep 1999 02:16:49 -0600
Received: from mars.superlink.net (root@xxxxxxxxxxxxxxxxxx [209.236.128.133])
by freeze.metastock.com (8.8.5/8.8.5) with ESMTP id LAA04303
for <metastock@xxxxxxxxxxxxx>; Fri, 17 Sep 1999 11:59:48 -0600 (MDT)
Received: from superlink.com (209.236.135.47.dialup.superlink.net [209.236.135.47])
by mars.superlink.net (8.9.3/8.9.3) with ESMTP id NAA13269
for <metastock@xxxxxxxxxxxxx>; Fri, 17 Sep 1999 13:46:00 -0400 (EDT)
Message-ID: <37E27DE0.11B4967A@xxxxxxxxxxxxx>
Date: Fri, 17 Sep 1999 13:44:01 -0400
From: Vitaly Larichev <vitaly@xxxxxxxxxxxxx>
X-Mailer: Mozilla 4.61 [en] (Win98; U)
X-Accept-Language: en
MIME-Version: 1.0
To: metastock@xxxxxxxxxxxxx
Subject: Re: Installation hangover
References: <001301be0a89$cc30cc60$51662599@xxxx> <37DA943D.82A2C25E@xxxxxxxxxxxxx>
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Sender: owner-metastock@xxxxxxxxxxxxx
Precedence: bulk
Reply-To: metastock@xxxxxxxxxxxxx
Status:
Seems I am working in a self-service mode - answering my own questions posted earlier :-) .
Lately, after installing MS 6.52 I've got too large fonts in Data Window and Title Bars of Inner
Windows, and too thick Title Bars themselves. This was the problem I struggled with last few days.
Since I've got no response to my question, it's quite probable that all other listers don't experience
these troubles or don't care, and this post with answers might be just a nuisance for many of you.
Well ... having finished with apologies, let me explain how you can change settings to fix this stuff,
or adjust if you wish.
To change fonts and the thickness of Title Bars, go to Control Panel/Display icon, choose Appearance
tab. Then click on "Palette Title" in "Item" menu. There choose Palette Title's size, font's type and
size. Mind different fonts has different smallest sizes which in turn determines smallest Bars'
thickness available. As for the font size in Data Window, I cannot pinpoint how I managed to make it
smaller. Perhaps, my monkeying with all those settings gave MS 6.52 a shake it needed to set the font
size right. Otherwise, cannot explain why with the same Control Panel settings MS 5.11 and 6.52 looked
different.
Cheers, Vitaly
Vitaly Larichev wrote:
> Hello everybody,
>
> Just installed MS 6.52 in the place of warm, fuzzy 5.11 <g>. It's fine. One thing I cannot figure
> out is how to change font size in Data Window. It's too large now, so that some values are cut off
> from the front: Volume for AT&T may read 3,567,000 instead of 13,567,000. Also it makes me scroll
> down too far if a chart is crowded with indicators.
>
> Another big problem is again too large font size in Title Bars of Inner Windows. It seems as if it
> also makes the bars so thick that they take out a good portion of screen real estate for a layout
> with 9 inner windows.
>
> Somehow in 5.11 I had all this small enough to like it.
>
> Thanks for any advice.
>
> Cheers, Vitaly.
|