EchoOff for WordBasic Macros

Based on materials originally presented by Steven S. Wexler

Steven S. Wexler is president of WexTech Systems, Inc., a consulting and training firm specializing in MicrosoftÒ WindowsÔ and AppleÒ MacintoshÒ applications.

Microsoft Corporation does not make any representation or warranty, express or implied, with respect to any information herein. Microsoft makes no warranty, implied or otherwise, regarding the performance or reliability of products manufactured by vendors independent of Microsoft.

Created: March 20, 1992

ABSTRACT

Have you ever wanted to stop screen updates when running a MicrosoftÒ Word for WindowsÔ macro? This article describes two subroutines, EchoOff and EchoOn, that use Windows dynamic link library (DLL) calls to duplicate the behavior of Microsoft Excel’s ECHO macro function for the active Word window. Because the EchoOff subroutine inhibits all redrawing of a window until you call EchoOn or restart Word for Windows, we advise caution and good debugging when using these subroutines.

WHAT DO YOU MEAN, ACTIVE WINDOW?

The WordBasic Echo macro has two subroutines, EchoOff and EchoOn, that disable and enable screen redraw. EchoOff turns off the screen redraw for the active window only. (The active window is defined as the window that is receiving user input.) When you open another window (or just a header pane, for that matter), the MicrosoftÒ Word for WindowsÔ word-processing program treats the window as a new entity and redraws everything. However, the initial window is still frozen and will stay that way until you force the window to be redrawn by turning echo on.

A GREAT WAY TO REALLY CONFUSE THE USER

If you think a simple macro error dialog box can confuse a user, wait until you write a macro that crashes before you get a chance to turn echo back on.

The problem confused us, too. We ran a macro with echo off and encountered a bug. We activated the macro sheet to examine the offending code highlighted in red. When we reactivated the original window, the title bar changed, but the window contents did not. We were in the macro editor but couldn’t select any text because an invisible window—the window we hadn’t redrawn—prevented us from doing anything. It took two reboots before we realized that we simply needed to turn echo on.

The Echo macro is stored in the global template NORMAL.DOT. Echo is usually called by another macro that passes it parameters to turn off redraw or to force a redraw. If you run Echo from the Tools Macro dialog box, it redraws the active window. This may not help your flummoxed user, but it provides an effective escape hatch when you’re debugging code.

HOW TO USE ECHO

The EchoOff and EchoOn subroutines are called by other Word for Windows macros, using the new Word for Windows version 2.0 feature for passing parameters between subroutines and functions in different macros.

To Turn Echo Off

The syntax for turning echo off is:

Echo.EchoOff IniKey$

where Echo is the name of the macro, EchoOff is the name of the subroutine within the macro, and IniKey$ is the name of the WIN.INI key used to store a value for turning echo on. This subroutine turns off redraw and saves the position of the scroll box in the vertical scroll bar of the active window to the WIN.INI file. The information is stored in the [Microsoft Word Echo] section of WIN.INI, under the IniKey$ key string. We’ll see exactly how this works when we dissect the macro.

Note:

The subroutine requires that you pass in a key string instead of saving this information to a generic key in WIN.INI. This allows you to use EchoOff for several windows simultaneously. If you prefer to store this information in your private initialization file instead of the WIN.INI file, see the Using Private Initialization Files with WordBasic article.

To Turn Echo On

The syntax for turning echo on is:

Echo.EchoOn IniKey$

where Echo is the name of the macro, EchoOn is the name of the subroutine within the macro, and IniKey$ is the key string in the WIN.INI file that retrieves the scroll position saved by the EchoOff subroutine.

HOW THE MACRO WORKS

The Echo macro contains the following lines:

Declare Function SendMessage Lib "user"(hWnd As Integer, \

wMsg As Integer,wParam As Integer, lParam As Long) As Long

Declare Function GetFocus Lib "user" As Integer

Declare Sub InvalidateRect Lib "user"(hWnd As Integer, \

lpRect As Long, Bool As Integer)

Declare Sub UpdateWindow Lib "user"(hWnd As Integer)

Sub MAIN

Echo 1, ""

End Sub

Sub Echo(fOn, IniKey$)

WM_SETREDRAW = 11

IniSection$ = "Microsoft Word Echo"

FocusHandle = GetFocus

If fOn = 0 Then

SetProfileString(IniSection$, IniKey$, Str$(VScroll()))

End If

dummy = SendMessage(FocusHandle, WM_SETREDRAW, fOn, 0)

If fOn Then

InvalidateRect(FocusHandle, 0, 1)

UpdateWindow(FocusHandle)

VScroll Val(GetProfileString$(IniSection$, IniKey$))

End If

End Sub

Sub EchoOff(IniKey$)

Echo 0, IniKey$

End Sub

Sub EchoOn(IniKey$)

Echo 1, IniKey$

End Sub

The Microsoft Windows Functions

First, let’s understand the purpose of the Windows functions. The statement:

Declare Function SendMessage Lib "user"(hWnd As Integer, \
wMsg As Integer, wParam As Integer, lParam As Long) As Long

lets us send messages to the Windows graphical environment.

Declare Function GetFocus Lib "user" As Integer

lets us determine which window is active.

Declare Sub InvalidateRect Lib "user"(hWnd As Integer, \
lpRect As Long, Bool As Integer)

lets us tell Windows that everything in the window needs repainting.

Declare Sub UpdateWindow Lib "user"(hWnd As Integer)

lets us redraw the window.

The EchoOff Subroutine

The statements:

Sub EchoOff(IniKey$)
Echo 0, IniKey$
End Sub

define a subroutine called EchoOff that accepts a single parameter called IniKey$. The IniKey$ variable contains the string that appears on the left side of the equal sign in WIN.INI. The value of the current vertical scroll position is stored on the right side of the equal sign. This value lets us reset the correct scroll position of the vertical scroll bar when EchoOn is used. The macro calls the primary subroutine Echo and passes it two parameters: 0 (meaning don’t redraw) and the IniKey$ parameter.

The Echo Primary Subroutine

The line:

Sub Echo(fOn, IniKey$)

defines the Echo macro and its two parameters, fOn and IniKey$.

The statement:

WM_SETREDRAW = 11

assigns the WM_SETREDRAW variable a value of 11. This value was obtained from the WINDOWS.H file; it tells Windows the type of message to send when it’s time to send a message.

The statement:

IniSection$ = "Microsoft Word Echo"

assigns the string “Microsoft Word Echo” to the variable IniSection$. This string is used as the section name in the WIN.INI file, that is, a [Microsoft Word Echo] section is added to WIN.INI if it does not already exist, and all WIN.INI settings set below will appear immediately below this label.

The statement:

FocusHandle = GetFocus

tells us the number of the active window. We need this information to identify the “name” or the handle of the window with which we want to communicate.

The lines:

If fOn = 0 Then
SetProfileString(IniSection$, IniKey$, Str$(VScroll()))
End If

tells Windows that if the value of fOn is 0—meaning we want to turn echo off—we want to save the current vertical scroll position to WIN.INI as a percentage of the length of the document (that’s the value returned by the VScroll function). Because WIN.INI only stores text strings, we use the Str$ function to convert the value returned by VScroll to a string. If the IniKey$ variable contained the string “Echo1” and VScroll returned the value 50, your WIN.INI file would look like this:

[Microsoft Word Echo]

Echo1= 50

We’ll need this information later when we want to turn echo back on.

The line:

dummy = SendMessage(FocusHandle, WM_SETREDRAW, fOn, 0)

tells Word for Windows to send a message to the active window (identified by FocusHandle). The message is stored in WM_SETREDRAW, whose value of 11 is interpreted as a redraw command. The value of fOn tells Windows to turn redraw on (if fOn = 1) or off (if fOn = 0). The 0 at the end of the parameter list isn’t used for this particular function but must be included. The dummy variable is never used but must be assigned a value because the Windows SendMessage function returns a value and WordBasic will not let you use a function without performing an explicit or implicit assignment of its return value.

The EchoOn Subroutine

The EchoOn subroutine works like EchoOff but sets fOn to 1 and runs additional lines from the Echo subroutine. The statement:

InvalidateRect(FocusHandle, 0, 1)

tells Windows that everything in the window will need to be repainted. The line:

UpdateWindow(FocusHandle)

tells Windows to actually repaint the window.

VScroll Val(GetProfileString$(IniSection$, IniKey$))

retrieves the vertical scroll position (the position at the time you turned echo off) from the WIN.INI file, converts it back into a numeric value, and resets the position of the scroll box on the vertical scroll bar to the saved position.

A FINAL WARNING

Use the Echo macro at your own risk. It has performed admirably for us so far with one exception: When you execute a macro defining a bookmark that isn’t only an insertion point, the bookmark is not always defined correctly. To remedy the situation, turn echo on just before you issue the bookmark command, and turn it off immediately afterward.

We leave it up to the user to explore and find all the ways Echo can be useful or harmful in your macro writing.