|Top||Optimizing Windows||Applications||Power Windows|
By John Woram
Click Here to see a
50.7 KB bitmap image of artwork
which goes with this article, entitled:
I USED TO THINK animated mouse pointers were little more than nice gimmicks. On my system, a yellow jacket fluttering its wings indicates a background operation is going on, and a Portuguese man-of-war means the system is busy.
A few days ago, both these pointers from the Microsoft Plus Dangerous Creatures configuration died. I had some work to do, so I figured I'd just let the little critters rest in peace until I had some spare time to play Frankenstein.
I soon found a lot of spare time, because my system had slowed down noticeably. A peek at the Performance Tab in Control Panel's System icon revealed the bad news. The File System line indicated some drives were using MS-DOS compatibility, and another warning stated that compatibility-mode paging was reducing overall system performance. More messages followed explaining that my C and D hard disk partitions were using the MS-DOS compatibility-mode file system. I'm all for compatibility, but in this case it looked more like a bug than a feature. I'd just as soon get back up to speed, even if it means being incompatible with something. If you feel the same, you might be interested in knowing what can cause compatibility-mode problems, and what you can do to fix them.
The MS-DOS compatibility mode is just Microspeak for a condition in which Win95 disables one or more protected-mode components in favor of the older real-mode components. Neither Windows Help nor the Windows 95 Resource Kit offers any information about this condition. But you can learn something about it via the System Properties' Help button. Select the Performance tab, click on the question mark in the upper right-hand corner, then drag the floating question mark down to the File System line and click again. You'll learn that "Windows will perform best using a 32-bit file system." You'll also learn that "Your disks will be slower if you are using MS-DOS compatibility mode."
So, why use compatibility mode? Well, if your system previously hosted Windows 3.1x or DOS 6.x, you probably loaded a few real-mode drivers and TSRs via your CONFIG.SYS and AUTOEXEC.BAT files. The Win95 setup procedure should recognize each one, disable it and substitute its own protected-mode driver. But if there's an older driver Win95 can't replace, it goes into its compatibility mode so the device the driver supports can function properly. Depending on specific configuration details, the system may take a performance hit. The hit's severity varies according to the device that still needs real-mode support.
The animated mouse pointer is a handy compatibility-mode indicator, behaving much like a canary in a coal mine. In either environment, you know there's trouble if the little creature stops moving. If you happen to be in a coal mine, get out quickly and find yourself another canary. Otherwise, just open Control Panel/System, select the Performance tab and note which components report the compatibility mode. If a newly installed device created the problem, you may see a Performance warning message as Windows opens. In this case, just click on the Yes button to proceed directly to the Performance tab for the bad news.
Next, look in CONFIG.SYS or AUTOEXEC.BAT for anything related to the device operating in compatibility mode. Disable the appropriate line(s) and reboot the system. If Windows doesn't discover the device that the disabled real-mode driver used to support, go to Control Panel/Add New Hardware to find the device. Or, you can do this first, and Win95 should offer to remove the real-mode components from your startup files.
This step may not lead anywhere though, especially if you no longer have a CONFIG.SYS or AUTOEXEC.BAT file. In that case you'll have to do more digging. You can look for trouble in two places. First, search the Windows folder for a new file named IOS.LOG. The first few lines of the file will offer some clues, such as these examples:
Unsafe driver filename controlling unit 0x.
Unit number 0x going through real-mode drivers.
Here, filename is the device driver causing the problem. Unit 0x, or Unit number 0x, indirectly indicates the affected drive-00 is drive A, 01 is drive B, 02 is drive C and so on. More specific information may follow. Look for a Driver Name section that lists a CONFIG.SYS line number greater than zero. If you find one, the specific filename is listed at the head of that section, and the cited line number tells you where to look in CONFIG.SYS.
The "Unsafe driver" nomenclature means Win95 knows it's not safe to replace the cited driver with its own protected-mode version. It knows this because it consults the IOS.INI file whenever it discovers a real-mode driver in CONFIG.SYS. If the driver is in the [SafeList] section, Win95 knows it's okay to disable and replace it. You can demonstrate this by loading a driver you know is safe, such as RAMDRIVE.SYS in the C: \WINDOWS directory. Then find that filename in IOS.INI and put a semicolon at the beginning of the line to disable it. This tricks Win95 into thinking RAMDRIVE.SYS is unsafe, and it will open in compatibility mode the next time you boot the system.
As another troubleshooting alternative, reboot the system and press F8 when the Starting Windows 95 message appears. Then choose the Startup menu's option 2 (\BOOTLOG.TXT). When Win95 opens, find the hidden BOOTLOG.TXT file in the root folder and double-click on it to view it in Notepad. Search for the word Failed and note each line on which it appears.
Interpret this information carefully though, because you may find one or more such lines that are potentially misleading. For instance, you may find an ebios failure, which simply means your system doesn't have extended BIOS, and therefore Win95 didn't load the ebios driver. Or you may discover an NDIS driver, VSERVER.VXD, vshare or other failed item that isn't really a failure at all.
The best defense against this sort of ambiguity is to run a BOOTLOG.TXT start-up when you know the system is functioning properly, and make a note of all the failed devices. Keep the list for future reference, then look for new failed devices whenever you have to troubleshoot a compatibility-mode problem. You may not find any new failures, but if you do, the cited file is probably corrupt or missing. In this case, the solution is to expand a fresh copy of the file into the appropriate directory.
It's possible none of the above actions will help you find and resolve a compatibility-mode problem. Were that not the case, I'd still be looking for something to write about this month. Remember my dead mouse pointers? I knew it couldn't be a startup file problem because I don't have any. This is (or was) a squeaky-clean machine; no CONFIG.SYS, no AUTOEXEC.BAT, no new errors in BOOTLOG.TXT and nothing else to point to the culprit. In fact, I'd done nothing to deserve this grief. Nothing but insert a no-name PCMCIA-to-SCSI adapter, which installed flawlessly. Or so I thought.
It turns out the installation process wrote a little something into the Registry that convinced Win95 to go into compatibility mode the next time I powered up. Other than that, the card itself was functional, as was an attached external SCSI device. It was easy enough to use Device Manager to remove the adapter. Unfortunately, doing so didn't remove the problem.
Because it wasn't clear which Registry entry caused the problem, or why that entry was left behind when I uninstalled the card, I simply imported my backed-up Registry file. You know the one I mean'the one you always make before you do anything potentially hazardous to your PC's health, like installing a no-name card. Odds are you'll never need such a file. In more than a year of beta and other Win95 testing, I've never needed to recover the Registry as a result of an installation malfunction-except once, when my virtual canary died. And then, we were both glad I'd exported the entire Registry before inserting that new PC card.
By the way, if a catastrophic Registry problem prevents Win95 from loading in anything but its Safe Mode, you can restore a backed-up Registry by booting to the command prompt. Then type REGEDIT /C filename.REG, where filename is the name (and path, if necessary) of that backed-up Registry file. If you forgot to make one, you may still be able to recover by copying the SYSTEM.DA0 and USER.DA0 files to SYSTEM.DAT and USER.DAT, respectively. But this will work only if these DA0 files aren't also corrupt.
To protect yourself from future disaster, you can also make a backup copy of the Registry by typing REGEDIT /E filename.REG at the command prompt, but only if the Registry is not too large. Otherwise, you may see the following error message: "Error accessing the Registry: The file may not be complete."
The problem is there's not enough free conventional memory to handle the file export of a very large Registry. The solution is to export the Registry from within Win95 itself.
If you'd like to set up your own compatibility-mode monitor, and don't have Microsoft Plus installed, try the animated APPSTART.ANI and HOURGLAS.ANI pointer files included with Win95. Just make sure the animation works immediately after you install the pointer. If it doesn't, make sure the system isn't running in compatibility mode. If it is, resolve that problem first.
Next, reconfigure the system for 256 colors or greater. If it still doesn't work, you'll need to track down another driver that's compatible with animated mouse pointers. Once you've installed a suitable display driver, use these or any other animated mouse pointers for the Working in Background and Busy functions, and you'll have a handy visual warning of a compatibility-mode problem.
Speaking of warnings, I mentioned importing a backup Registry file as one way to recover from some compatibility-mode problems. If you do this from time to time, here's something to keep in mind. In most cases, associating a registered file type with a Windows application is a convenience. Just double-click on any file with a registered extension, and it loads into the appropriate application. However, you may want to disable this function for Registry files, so Win95 won't import them into the Registry if you accidentally double-click on a file with an .REG extension. Open Explorer's View menu and select Options. Click on the File Types tab, scroll down to Registration Entries, highlight it and then click on the Remove button. A message warns that "If you remove a registered file type, you will not be able to open files of that type by double-clicking their icons." That's exactly what you want to prevent, so click on the Yes button. If you really do want to import these files, open the Registry Editor and select Registry/Import Registry File.
As another alternative, export the Registry into a file with, say, a .TXT extension. That way, if you double-click on it by accident, you'll just open the file in Notepad, or WordPad if it's too big for Notepad.
A bit of post-trauma diagnostics turned up the culprit that caused the compatibility-mode problem I described earlier. It turns out the .INF file accompanying the PC card had the following lines in it:
What does it all mean? In one sentence, "Delete the hdc (hard disk controller) subkey in the HKEY_LOCAL_MACHINE section of the Registry." No doubt there's a reason for this, but I'm not sure what it is.
Moral? If you're about to install something new, and you're not sure of its implications on the total system, scan the accompanying .INF file for any section name with the magic word del_reg in it. If you find one, and have your doubts about why you should delete it, export that section of the Registry into its own file. If all does not go well, you can import it back in again and possibly recover without too much further grief.
Senior Contributing Editor John Woram is the author of Windows Configuration Handbook (Random House, 1993). Contact John in the "Optimizing Windows" topic of WINDOWS Magazine's areas on America Online and CompuServe. To find his E-Mail ID Click Here
|Top||Optimizing Windows||Applications||Power Windows|
By Jim Boyce
The whole idea behind computers is to make your job easier and make you more productive (for now, I'll ignore the therapeutic benefits of Solitaire and Freecell and how cool your PC looks on your desk).
Take a word processor, for instance. The spell checker corrects your spelling, the grammar checker corrects your grammar, and the document wizards format your document. Now if you could only get your PC to write the darn thing, you'd be windsurfing in the Caribbean. Your word processor may never completely free you up for a life of leisure, but it can automate a lot of your work.
Much of the writing I do is repetitive. Each book I write uses the same style and structure. When I refer to a figure, for instance, I use the same format in the manuscript to enter the figure number, caption and other information that tells the production department how and where to insert the figure. I could simply type the information each time I add a figure reference, but that would be a waste of processor power. After all, MS Word can insert all the boilerplate stuff for me; then, all I have to do is fill in the blanks. So, I've automated this process, saved keystrokes and cut my writing time-by using a macro. If you have similar bits of text or formatting you'd like to automate, all you need to do is create your own macro.
Even if you fall into the power user category, your exposure to macros may be limited to those that, say, record simple tasks for playback. Macros run the gamut from recorded keystrokes to masterpieces that look and act like standalone programs. Most complex macros require a considerable amount of time and programming skill to develop, but you can easily create macros that do more than just play back commands. Let's look at a macro that won't win any awards for complexity, but will give you an idea of how easy it is to automate common tasks.
Say you need to insert a paragraph in a lot of your documents that describes a product your company sells. The only variable is the price you quote. You need a simple macro that inserts the paragraph, then locates the cursor where you'd like to type in the product's price. This example assumes you're using Word for Windows 95, but the process is similar for previous versions.
First, start the macro by choosing Tools/Macro. In the Macro Name text field of the resulting dialog box, type a name for the macro, such as ProductDescription (no spaces allowed). Click in the Description text box and enter a short description of the macro's function (you can leave this blank if you choose). Next, click on the Create button. Word opens a new macro document window and automatically inserts the beginning and ending statements of the macro:
We'll tackle macro structure in a future column. For now, just be aware that all the macros you write will start with the Sub MAIN statement and end with the End Sub statement. You'll add your own macro statements in between.
Next, use the Insert statement to insert a paragraph into the document:
Insert "Thank you for considering the purchase of a Phase X framistat. The Phase X is the finest framistat on the market today. Our regular model has been discontinued, but we have a special gold-plated version available at a discount to our favorite customers for only $. To take advantage of this offer, please call me at your convenience."
That's all you need to do. Make sure to enclose the paragraph in quotation marks, as shown above. If you omit the closing quotes, you'll receive a syntax error message when you try to run the macro.
Next, you need to position the cursor right after the dollar sign so you can immediately type in the price du jour. There are a few methods that will work, but one of the simplest is to search up from the current cursor location (which will be at the end of the just-inserted paragraph) for the first occurrence of a dollar sign. This will select the dollar sign, so you'll have to add one more statement to move the cursor one character to the right, placing it just after the dollar sign.
To locate the dollar sign, use the EditFind statement. EditFind corresponds to the Find command in the Edit menu. Instead of choosing options from the Find dialog box, you specify the options with the EditFind statement. In this example, we'll specify the text to locate and the search direction (up), and direct the macro to ignore formatting in the search. Here's the statement to add:
EditFind .Find = "$", .Direction = 1, .Format = 0
The .Find option specifies the text to locate, which in this case is a dollar sign. Note that the text is enclosed in quotes. The .Direction option specifies the search direction. A value of 0 specifies a search toward the end of the document (down), and a value of 1 specifies a search toward the beginning of the document (up). The .Format option, if set to zero, directs the macro to ignore formatting when it performs the search. When you add this statement, make sure to include commas between the options-the macro will generate a syntax error if you leave them out.
The final statement to add in this simple macro is one that moves the cursor one character to the right; this will deselect the dollar sign and place the cursor in the correct location so you can type in the price. We'll use the CharRight statement, which moves the cursor a specified number of characters to the right:
The "1" in this statement specifies the number of characters to move the cursor. The "0" directs Word not to select (highlight) text as it moves the cursor. The result is that Word simply moves the cursor one character to the right.
Your macro is now finished. To save it, choose File/Close. Word will ask if you want to save the macro; choose Yes. At this point, you could run the macro by slogging through the Tools menu, but you want to speed things up, so let's assign it a shortcut key.
Choose Tools/Customize to display the Customize property sheet. Click on the Keyboard tab to display the Keyboard property page. Scroll through the Categories list to locate and choose Macros. The Macros list will display all of your available macros. Locate and select the macro you just wrote, then click on the Press New Shortcut Key text box. Press a shortcut key combination (Alt+Shift+G, for example), then choose the Assign button. Click on the Close button to close the dialog box.
Now, when you want to insert the paragraph, just press the shortcut key combo you assigned to the macro. Or you can choose Tools/Macro to select the macro, then click on the Run button in the Macro dialog box to run it. Either way, you'll get your work done a whole lot faster-and give yourself more time to practice your windsurfing.
Contributing Editor Jim Boyce is the lead author of Special Edition: Using Windows 95 Communications (Que, 1996). Contact Jim in the "Applications" topic of WINDOWS Magazine's areas on America Online and CompuServe. To find his E-Mail ID Click Here
|Top||Optimizing Windows||Applications||Power Windows|
By Karen Kenworthy
Click Here to see a
5.94 KB bitmap image of artwork
which goes with this article, entitled:
The Registry Holds the Keys
WINDOWS IS A blabbermouth. It's full of secrets and isn't the least bit shy about revealing them. When did you install Windows? How many colors can your video card display? What's your best Pinball score? Windows knows all this and more, and will tell anyone who asks.
Windows 3.1x stores many secrets in .INI files. But as Windows grew more complex, so did the .INI files. Before long, it was clear these files had to go. That's why Windows 95 and Windows NT come equipped with a Registry.
The Registry is a reasonably sophisticated database of configuration information, user preferences, program settings and more. Windows adds, deletes and changes entries in this database, although often at the request of other programs.
Windows comes with a program, REGEDIT.EXE, that lets you explore the Registry. The Registry's contents resemble those of a hard disk file system, which is no coincidence. After all, a file system is nothing more than a database that contains information about your disk files.
Like files on a hard disk, each Registry item has a unique pathname starting with one of six special keys. The rest of an item's path consists of one or more subkeys separated by backslashes and followed by a data name.
The heart of the matter is the actual data stored under a particular key, subkey(s) and data name. Windows has defined 10 types of data. Two of the more common data types are REG_DWORD (a 32-bit binary number) and REG_SZ (a string terminated by a null byte). There's also a catch-all data type, REG_BINARY, for large binary data items such as icons.
To help you use your Registry knowledge, I've written a small Visual Basic 4.0 (VB4) program that extracts several pieces of data from the Registry and displays them in a window. You need the 32-bit version of VB4 because the new Windows API calls that access the Registry are 32-bit only.
Because the program reveals some of Windows' deepest secrets, I've named it the WinMag Tattler. The Tattler is simple: As soon as the program loads, it retrieves its assigned pieces of Registry data. It then places each value in one of the main window's text boxes. It retrieves the Registry data only once, although you can easily instruct Tattler to update the data periodically, thus turning it into a Registry monitor. To do this, modify the program by adding a timer to cause the data retrieval to occur after every timer "tick."
Reading the Registry is a lot like reading a disk file. First, you need to open the Registry before you can read one or more data values. Then, you need to close the Registry. To perform these tasks, Tattler uses three new Windows API calls: RegOpenKeyEx (Registry Open Key Extended), RegQueryValueEx (Registry Query Value Extended) and RegCloseKey (Registry Close Key).
Before Tattler can retrieve any Registry data, it has to call Reg- OpenKeyEx. Once it tells Windows the path (key and subkeys) leading to the data you'll be retrieving, Windows uses this information to allocate memory it will need later to speed access to the Registry data. This function has five parameters:
1. One of the six special keys.
2. A string containing any subkeys.
3. A Long integer that must contain zero (this parameter is reserved for future enhancements).
4. A Long integer defining how you'll use the Registry.
5. A Long integer where Windows will store a "handle." You'll pass this handle back to Windows when you make your other Registry API calls.
Next, it's time to call RegQueryValueEx, which tells Windows the name of the data you'd like to see. Windows responds by sending you its value. This function has the following six parameters:
1. The handle your call to Reg-OpenKeyEx returned.
2. A string containing the name of the value you'd like retrieved.
3. A Long integer that must contain zero (as above, this parameter is reserved for future enhancements).
4. A Long integer where Windows stores a value indicating the data's type.
5. A variable where Windows will store the value it retrieves. This variable's type must match the type of the value being retrieved. If the value being retrieved is a string, it must be passed to Windows "By Value" (the VB4 keyword ByVal must precede its name).
6. A Long integer indicating the size (in bytes) of the variable used to store the value. Integers have a size of 2, while Long integers require 4 bytes. Strings can be of any size.
Finally, it's time to call RegCloseKey. This function tells Windows you've finished reading values along a particular path, so it can free the memory it used when you called RegOpenKeyEx.
Like all Windows API calls, these three must first be declared before they can be called within a VB program. Declare statements tell VB which Windows component carries out the API call (in this case, ADVAPI32.DLL), and what types of data are appropriate for each of the function's parameters. Below are the Declare statements Tattler needs to access the Registry, along with the definitions of a few important Constants.
Global Const HKEY_CLASSES_ROOT = &H80000000
Global Const HKEY_CURRENT_USER = &H80000001
Global Const HKEY_LOCAL_MACHINE = &H80000002
Global Const HKEY_USERS =&H80000003
Global Const HKEY_CURRENT_ CONFIG = &H80000005
Global Const HKEY_DYN_DATA = &H80000006
Global Const REG_SZ = 1
Global Const REG_BINARY = 3
Global Const REG_DWORD = 4
Global Const KEY_QUERY_VALUE = &H1
Declare Function Reg-OpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hkey As Long, ByVallpSubKey As String, ByVal lReserved As Long, ByVallSecurity As Long,phkResult As Long) As Long Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hkey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
Declare Function RegCloseKey Lib "advapi32.dll" (ByValhkey As Long) As Long
And here's a small program fragment that uses these three API calls to retrieve the log-on name of the current user:
Dim hkey As Long
Dim strData As String
Dim lType As Long
Dim lResult As Long
lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Network\Logon", 0, KEY_QUERY_VALUE, hkey)
If lResult = 0 Then ' Open request succeededstrData = Space(33)
lResult = RegQueryValueEx(hkey, "username", 0&, lType, ByVal strData, 32&)
If lResult = 0 Then ' Queryrequest succeeded
lblUserName.Caption = strData
lblUserName.Caption = "Unknown"
It starts by calling Reg-OpenKeyEx, thus informing Windows you'll be strolling down the path HKEY_LOCAL_MACHINE\Network\Logon. Windows responds by storing a handle in your variable hkey. It also returns a Long integer, which you store in lResult, indicating whether your open attempt succeeded.
If lResult equals zero, Reg-OpenKeyEx did its job. Now you must prepare the data's new home. The statement strData = Space(33) stores 33 spaces in strData, ensuring the variable will be large enough to hold the user name Windows will return.
Now it's time to call RegQueryValueEx. It sends Windows the handle you received a moment ago (hkey) and the name of the value you want to see (username). Windows responds by storing the value in strData, and a number indicating the data type (REG_SZ) in your variable lType. Once again, Windows returns a number indicating whether our request could be carried out.
Your program fragment finishes its job by storing the user name Windows provides in the Caption of one of its Text boxes (lblUserName). If, for any reason, your call to RegQueryValueEx fails, it displays the string "Unknown."
The Registry data values my version of Tattler displays aren't important. I chose them to demonstrate how to retrieve the most common data types, and to give you an idea of the variety of information available.
Changing Tattler to retrieve and display other values is easy. Just change the key and subkey fields in the call to RegOpen-KeyEx, and pass the appropriate variable and size when calling RegQueryValueEx. If you don't know the type of data ahead of time, call RegQueryValueEx with a size (parameter 5) of zero. Windows will then report the type of data, in parameter 4, without returning any data. You can then call RegQueryValueEx again, passing it the appropriate variable in parameter 5.
As usual, I've made the source code of the program available for download, so you can easily modify Tattler to reveal your favorite secrets. Look for pwtattlr.zip at WINDOWS Magazine's Online Locations .
Contributing Editor Karen Kenworthy is the author of Visual Basic for Applications, Revealed! (Prima Publishing, 1994) and the manager of the WINDOWS Magazine forums on America Online and CompuServe. Contact Karen in the "Power Windows" topic of these areas. To find her E-Mail ID Click Here