Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Schongar P.VBScript unleashed.1997

.pdf
Скачиваний:
43
Добавлен:
23.08.2013
Размер:
1.59 Mб
Скачать

<INPUT TYPE=BUTTON VALUE="Submit" NAME="BtnSubmit">

<INPUT TYPE=BUTTON VALUE="Clear" NAME="BtnClear">

<INPUT TYPE=BUTTON VALUE="Init" NAME="BtnInit"><BR>

</PRE>

Listing 20.6 shows the VBScript code used to process the data entered by the user. This code also processes the mouse click events when the user clicks the Submit, Clear, or Init buttons. Prior to JavaScript and VBScript, such processing would occur on the server using CGI programs and scripts. VBScript extends the HTML code and validates user input before it is sent to the server. This setup reduces network traffic, decreases server load, and improves the overall performance of your Web page.

Two variants and six procedures get defined: strMsgBoxTitle and bValidOrder and Window_OnLoad,

BtnInit_OnClick, BtnSubmit_OnClick, ValidateDeliveryDate, CheckSpecified, and BtnClear_OnClick.

The subroutine Window_OnLoad gets executed when the Web page window is first loaded by the browser. It assigns the value MSFID to the variant strMsgBoxTitle. The variant StrMsgBoxTitle is assigned a string value; therefore, it is now a string variable. The strMsgBoxTitle is used to display the title for the message box. Next the subroutine Window_OnLoad calls the BtnInit_OnClick procedure. This procedure initializes the data-entry fields.

The procedure BtnInit_OnClick initializes the data-entry fields. It is executed when the Web page window is first loaded. It also gets executed when the user clicks the Init button.

The procedure BtnSubmit_OnClick gets executed when the user clicks the Submit button. It checks to make sure if the data entered is valid. If it is valid, the variable bValidOrder is initialized to true at the beginning of this procedure and retains its initialized value. If bValidOrder is true, the order gets sent. If the data entered is invalid, bValidOrder is set to false and the control is returned to the user on the Web page.

The procedure ValidDeliveryDate determines whether the value specified in the date field is valid.

The procedure CheckSpecified is actually called by the BtnSubmit_OnClick procedure. It determines whether the data entered in name and address fields is valid.

The procedure BtnClear_OnClick is executed when the user clicks the Clear button. It clears the data-entry fields.

Listing 20.6. VBScript code for processing mouse clicks and user input.

<SCRIPT LANGUAGE="VBScript">

<!--

Option Explicit

Dim strMsgBoxTitle

Dim bValidOrder

Sub Window_OnLoad

strMsgBoxTitle = "MSFTD"

Call BtnInit_OnClick

End Sub

Sub BtnInit_OnClick

TxtName.Value = "Joe Smith"

TxtAddress.Value = "1 Main Street"

TxtCity.Value = "Springfield"

TxtState.Value = "Washington"

TxtZip.Value = "12345"

TxtDate.Value = Date + 3

End Sub

Sub BtnSubmit_OnClick

bValidOrder = True

Call CheckSpecified(txtName.Value, "Please specify a name.")

Call CheckSpecified(txtAddress.Value, "Please specify an address.")

Call CheckSpecified(txtCity.Value, "Please specify a city.")

Call CheckSpecified(txtState.Value, "Please specify a state.")

Call CheckSpecified(txtZip.Value, "Please specify a zip code.")

Call CheckSpecified(txtDate.Value, "Please specify a date.")

Call ValidateDeliveryDate

If bValidOrder Then

MsgBox "Thank you for your order!", 0, strMsgBoxTitle

' TODO: Actually send the order.

End If

End Sub

Sub ValidateDeliveryDate

Dim SoonestWeCanDeliver

Dim RequestedDate

If Not bValidOrder Then Exit Sub

SoonestWeCanDeliver = Date + 2

RequestedDate = CDate(TxtDate.Value)

If RequestedDate < SoonestWeCanDeliver Then

bValidOrder = False

MsgBox "Not even we can deliver that fast!", 0, strMsgBoxTitle

End If

End Sub

Sub CheckSpecified(ByVal strFieldValue, ByVal strMsg)

If strFieldValue = "" And bValidOrder Then

MsgBox strMsg, 0, strMsgBoxTitle

bValidOrder = False

End If

End Sub

Sub BtnClear_OnClick

TxtName.Value = ""

TxtAddress.Value = ""

TxtCity.Value = ""

TxtState.Value = ""

TxtZip.Value = ""

TxtDate.Value = ""

End Sub

-->

</SCRIPT>

The remaining part of the code is again all HTML. It remains the same no matter whether you use CGI or VBScript. In this example, all the VBScript code is encapsulated between the <SCRIPT> and </SCRIPT> tags. The entire code resides in a single location within the body of the HTML code, making the code modular and easy to locate. The VBScript code is listed in the <BODY> section of the HTML code.

Relevant Web Sites

Table 20.1 lists few Web sites for more information on CGI and VBScript. Plenty of resources and examples exist on the Internet.

Table 20.1. Relevant Web sites.

Site Name

Site URL

World Wide Web Consortium

http://www.w3.org

Perl CGI scripts for Internet Retailers

http://phoenixrise.com/CCC/cindex.

 

html

VBScript

http://www.microsoft.com/vbscript

VBScript links

http://www.microsoft.com/vbscript/

 

us/

 

vbsmain/vbslinks.htm

Review

CGI represents a simple protocol of communication between the Web forms and your programs that reside on the Web server. A CGI script or program gets its input from the Web forms, processes it, and sends the results back to your browser. CGI is not a programming language; it is a script or a program that resides on the server. You can create a CGI script or program using almost any programming language that supports standard input and output processing. For example, you can use C/C++, Visual Basic, Perl, or FORTRAN to write your CGI programs. The best language to use is the one that you feel familiar with and comfortable using. Whatever you choose, make sure your CGI programs process data efficiently and respond quickly. Remember, CGI programs get their input from the Web forms, and the user waits for the response while the data is being processed. Therefore, the CGI programs need to respond quickly.

You have two important decisions to make about CGI early on for your project. First, decide whether your project demands the use of CGI. Then, you have to decide how to protect the CGI programs. Because a CGI program is invoked as a result of user action through the browser, you need to undertake necessary security precautions. The CGI programs should be under direct control of the Webmaster only and all others should have only execute rights.

VBScript programming is simpler than CGI programming. This chapter introduced CGI and explained the different CGI environment variables. It compared CGI with VBScript and identified how VBScript can be used to handle some of the processing on the client side, thus eliminating or reducing the need for CGI scripts and reducing the load on the network and server. Data communication in a CGI-based web architecture was also discussed. This chapter also included examples of VBScript code for processing mouse clicks and user input. There is plenty of resources and examples available on the Net. A list of few relevant and useful web sites is included in this chapter. Be sure to visit the Microsoft VBScript site regularly to keep abreast of the latest on Microsoft Internet Explorer and VBScript. VBScript is the new kid on the block and it is expected to grow and evolve over time.

If you use CGI scripts to process user input and mouse clicks, you load the server with many trivial tasks that could very easily be handled on the client side. You also increase network traffic. This setup creates an inefficient use of the server and its processing power. Using VBScript to handle such tasks reduces network traffic and server load.

Chapter 19

VBScript and DLLs

by Ramesh Chandak

CONTENTS

Static Versus Dynamic Library

Structure of a DLL

The Entry Function

The LibMain Function

The Exit Function

Programmer-Defined Functions

Exported Functions

Non-Exported (Internal) Functions

Why Use DLLs?

Disadvantages of Using DLLs

A Sample DLL

VBScript and DLLs

Relevant Web Sites

Review

The concept of DLL, which stands for dynamic link library, first appeared with the release of the Windows operating system. Simply put, a DLL is a collection of functions. It is dynamically linked at runtime with your application's executable and helps you extend the functionality of the base function call library of any Windows application. (See Figure 19.1.) This chapter introduces DLLs and discusses their advantages and disadvantages. It compares and contrasts DLLs with static libraries. You will learn more about the structure of a DLL. You will also learn about where and how you can define your own functions within a DLL. This chapter discusses VBScript's lack of support for DLLs and how it affects your code.

Figure 19.1 : A dynamic link library is loaded into memory at runtime.

DLLs are likely to create distribution nightmares. Just like any other software, a DLL will probably get upgraded over time. Consequently, you end up having several different versions of DLLs. When writing your installation utility, you need to consider the possibility of older versions of DLLs residing on your user's system and be careful when you install new versions of the same DLLs. With the introduction of 32-bit-based Windows 95, programmers and developers have to be aware of the 16and 32-bit versions of the same DLLs. DLL management becomes important in such cases.

DLLs might have any file extension (.res, .fon, .exe, or .dll, for example). A DLL program does not include the main() or winmain() functions. Instead, it contains the functions Entry, LibMain, and Exit.

A large pool of third-party developers for Visual Basic and other Microsoft programming tools have created a tremendous number of enhanced controls and libraries for use with your Windows applications. Most of these controls

and libraries are nothing but DLLs. Developers have created DLLs that handle not only complex mathematical calculations, but also provide enhanced user interface controls. A DLL is usually written using C or C++, which is a big advantage because it provides speed and efficiency. Using DLLs to handle numeric-intensive tasks, while using your favorite GUI tool for the user interface of your application, is highly recommended as it offers code modularity, speed, and efficiency.

Windows 95 has three main DLLs : gdi32.exe, user32.exe, and kernel32.exe. Windows 3.1 comprises of the same three DLLs, but uses their 16-bit versions: gdi.exe, user.exe, and kernel.exe.

NOTE

Usually DLL files have the .dll extension. Windows DLLs have the . exe extension; however, they are still DLLs.

Each DLL consists of function calls that constitute the entire Windows function call library. By default, these DLLs reside in the system subdirectory of your Windows directory (c:\windows\system, for example).

Windows 3.1 is a single-threaded, cooperative multitasking system. Unlike OS/2 or Windows NT, only one thread of execution can be active at any given time in a given application. The primary difference between a Windows application and a Windows DLL is that Windows tasks get entered into TDB-the task database. The task database is an internal Windows object. Therefore, a Windows application gets the resources, such as stack segment, message queue, file handle table, DOS path, and environment block, but a DLL does not get these items directly. The DLL borrows them from the Windows application that calls it.

Static Versus Dynamic Library

A static library is linked into your executable code. It is part of the executable, thus creating a larger executable file. A larger executable file requires more RAM and disk space. On the other hand, a static library is faster than a DLL because it has already linked into the executable and loaded into memory when the executable is first run. Before it can be used, a programmer-defined DLL must be loaded into memory, if that has not already occurred.

NOTE

A Windows DLL is already loaded when Windows starts up, so it does not have to be specifically loaded into memory at runtime.

A large executable takes more time to load into memory. Also, the static library has to have a link into every executable that needs it. Consequently, if you have three different executables that need a static library, this static library must be linked into all three executables. And if all three executables run at the same time, you have three copies of the static library loaded into the memory space, which makes for inefficient use of memory space. No code sharing exists across applications, which is where dynamic link libraries come into picture. A dynamic link library is loaded only at runtime. And only one copy of the library needs to get loaded into the memory space. The library can be shared across applications if more than one application needs it. An application can even unload the DLL if it is not needed at any given point in time, and thus free up some memory.

The executable file contains references to the functions in the DLL. If you create ten different programs that use the same library, you need to create only one DLL, which saves memory and disk space. Primarily, a DLL works to reduce the load image of an EXE, as well as share resources across multiple executables or instances of an executable. You can update these DLLs without re-linking because the executable contains references and not the actual code.

NOTE

Static libraries offer better performance. DLLs offer better memory management.

DLLs have been known to create distribution nightmares. Just like any other application is upgraded over time, a DLL is also likely to be upgraded. You may add new functions to a DLL or enhance existing ones. You may port a 16-bit DLL to a 32-bit or upgrade simply because the host application has been upgraded. To accommodate such scenarios, you need to consider in your installation utility that older versions of DLLs might reside on your user's system-so be careful when you install new versions of the same DLLs. Consider this real-world example. A Visual Basic 3.0 application was designed using Microsoft Access 1.1 as the back-end database. Another Visual Basic 3.0 application was designed that uses Microsoft Access 2.0 as the back-end database and the Jet Engine compatibility layer to make Visual Basic 3.0 talk to Microsoft Access 2.0. After installing the second application on the same machine as the first one, the first application stopped working. It gave an error message, Reserved Error (which is not documented in any of the Visual Basic or Microsoft Access documentation). It became very difficult to debug. Later it was realized that the first application did not work anymore because it was using the Jet Engine compatibility layer, although the database was still version 1.1-not upgraded to version 2.0. It was using the Access version 2.0 DLLs when in fact it should have been using the version 1.1 DLLs. The version 2.0 DLLs were resident in the same directory as the version 1.1 DLLs-the \windows\system directory.

Both static and dynamic libraries have advantages and disadvantages. The trend in Windows development utilizes DLLs. DLL technology is developed and promoted by Microsoft. Microsoft anticipates, expects, and hopes every user will use its products, from Microsoft Word to Visual FoxPro to Microsoft Access. Many of these applications utilize the same DLLs, which supports why DLL technology makes sense. If you are using Microsoft Word and Microsoft Excel, for example, and they utilize the same three DLLs, only one copy of each DLL gets loaded into memory.

In order for you to run a program that uses a dynamic library, the library must be present on the disk, either in the current directory, a directory accessible through the PATH string in MS-DOS, the Windows directory, or the SYSTEM subdirectory of the Windows directory. If the library does not appear in any of these locations, you get a runtime application error. The best place to install your application DLLs is in your application directory, and you should include it in the PATH string. Any Windows DLLs must be installed in the \windows\system directory.

With the introduction of 32-bit-based Windows 95, programmers and developers have to think about the 16and 32-bit versions of the same DLLs. DLL management becomes important in such cases.

NOTE

DLL distribution and management becomes critical for the success of any DLL-based application. When you release upgrades and fixes, make sure the installation utility does not cause any unnecessary overwrites and deletes of existing DLLs.

Structure of a DLL

Any standard Windows application includes the main() or winmain() function. You can run an application by double-clicking its executable (.exe). The main() or winmain() function is the starting point for the application. Within the main() function, you include all the code necessary to perform the required tasks, including calling other functions or functions within a DLL. On the other hand, you cannot run a DLL simply by double-clicking on it.

The Entry Function

Once the Windows loader has loaded a DLL into memory, it transfers execution to the DLL's entry-point function, which performs whatever initialization the DLL needs to function properly. The name of LibEntry.Obj is different for different platforms. LibEntry's most important task is to initialize the DLL's local heap, if it has one. Without a local heap the DLL cannot use any of Windows' local memory management APIs. Once it has initialized the DLL's local heap, LibEntry usually calls a programmer-specified function to perform any additional initialization required by the DLL.

You may wonder why all initialization does not occur in LibEntry instead of calling a programmer-specified function. LibEntry is written in Assembly language for performance reasons. Any changes or additions to the LibEntry.Obj have to occur in Assembly language. Programming is easier in a high-level language, such as C or C++, than in Assembly language.

Writing the minimum code necessary in LibEntry using Assembly language is easier; then you call a function and write that function in a high-level language. LibEntry.Obj, a runtime object file, is linked by the built-in C++ compiler at build time. If this function fails, Windows unloads the DLL from memory; otherwise it calls LibMain. If LibMain returns false, Windows unloads the DLL from memory. Note that you cannot have multiple instances of the same DLL in memory; moreover, LibEntry and LibMain get called only once, no matter how many applications share the same DLL. If you want to perform additional initialization for each instance of your application, you should provide an exported function and call that function instead.

The LibMain Function

LibMain is a programmer-defined initialization function called by LibEntry. Because LibEntry performs initializations that are common to all DLLs, you can write your DLL-specific initialization in LibMain. Because this represents a separate function from LibEntry, you can write it in a high-level language instead of writing in Assembly language. Listing 19.1 shows the LibMain function.

Listing 19.1. The LibMain function.

/* You may modify it in any way you wish but do not remove Libmain and WEP.

Without them you will be unable to link your DLL. */

#include <windows.h>

int _export LibMain( HANDLE hmod, WORD dataseg, WORD heap, LPSTR cmdline)

{

hmod = hmod;

// these assignements generate no

code

 

dataseg = dataseg;

// but prevent compiler warnings

about

 

heap = heap;

// unreferenced variables

cmdline = cmdline;

 

return( 1 );

 

}

Remember that this function is called only once. It can only perform an initialization that is independent of the application instances. You may want to use it to load resources, such as bitmaps or icons, or to create data structures that the DLL manages. Remember, however, not to write code in LibMain that depends on other previously loaded DLLs, because when several DLLs are to be loaded at one time, Windows does not load them in any guaranteed order.

The Exit Function

Windows Exit Procedure (WEP) is the last function of a DLL to be called before Windows unloads the DLL from memory. WEP performs any cleanup a DLL needs to do before it is unloaded and is called only once. When a DLL's usage count drops to zero, the Windows loader calls the DLL's WEP and then unloads the DLL. The usage count for an implicitly loaded DLL becomes zero after all instances of all applications that are currently using it exit. Listing 19.2 shows the WEP function.

Listing 19.2. The Windows Exit Procedure (WEP).

int _export WEP( int res )

{

res = res;

return( 1 );

}

Windows 3.0 requires this function for all DLLs. In Windows 3.1 and later versions, WEP is optional.

Programmer-Defined Functions

These functions enable you to actually implement the functionality you want-they represent the real workhorses of the DLL. Programmer-defined functions implement the functionality of DLLs in two varieties: exported and non-exported.

When declaring functions within a DLL, certain conventions should be followed, as specified in the Windows SDK. You need to use the ANSI keywords far, pascal, and export.

The FAR declaration helps Windows change the code segment of any program as required by the memory manager. The references to specific keywords such as FAR or NEAR do not apply in a 32-bit environment.

PASCAL function calls are more efficient than C function calls. With PASCAL function calls, the responsibility of managing parameters and cleaning up the stack remains with the called procedure. Under C function calls, the calling