Tips - September 1994
This quarter we're bringing you a whole bunch of tips and techniques directly from development!
TIP: When developing a device driver on a single machine, many boot cycles are required for testing. You can install a small bootable partition that contain a line pointing to the device driver under development. No changes to CONFIG.SYS files are needed between booting into the test environment or the development environment. There is no risk of making the primary environment unbootable.
TIP: Bring up the VisualAge product faster!
TECHNIQUE: Make sure the drive on which the SWAPPER.DAT file exists has a good amount of free space, then change the second numeric value of the SWAPPATH statement in the CONFIG.SYS file from 2 MB to 20 MB:
SWAPPATH=C:\OS2\SYSTEM 2048 20480
The second numeric parameter is the initial size of SWAPPER.DAT in kilobytes. After you reboot, OS/2 will allocate SWAPPER.DAT at 20 MB size instead of the default 2 MB size.
TIP: Improve your performance!
TECHNIQUE: Move your swapfile to the root directory of the partition you use the most of the drive you use the least. You also can designate that the swapfile be larger than the default. Do this using the SWAPPATH= statement in the CONFIG.SYS file.
TIP: Stop having trouble finding objects on your desktop!
TECHNIQUE: The OS/2 Desktop is a folder, and just like any other folder, it can be opened in one of three standard views:
- Icon View
- Tree View
- Details View
The default OS/2 installation sets up your system so that you can have only one copy of each view open at a time*, but that doesn't mean only one view at a time! You can have all three of these views open at the same time, and work in any one you like.
Remember that these are different views of the same data, so anything you do in one view will be reflected in the other views as well. If you Arrange objects in one view, the objects in all other views are arranged as well; if you delete or move an open from one view, the object is deleted/moved from all other views. You also can open an object from any of these views as well!
If you want to act on an object on your Desktop, but you can't see the object because there are open windows over it, all you have to do is open another view of the Desktop - say, the Details View - and act on (open, move, delete, ...) the object from the new view!
- This is the default setting, but you can modify this behavior of any folder by opening the Settings for the folder, selecting the Window page, and then modifying the Open Object behavior from Display existing window to Create new window. If you do this, you can have multiple copies of each view open at the same time.
Device Driver Tips:
TIP: Writing an OS/2 device driver? Get ready for OS/2 for PowerPC by layering your device driver similar to the ADD model, separating the hardware specific layer form the software layer. This will provide you with the least work when moving your drivers to OS/2 for PowerPC.
TIP: Still writing your driver in assembly language? Try to write them in C from now on. The current direction in operating systems is to make most device drivers hardware-independent and to have them run as an applications rather than kernel tasks. Writing your driver in a high-level language will make the move to systems, such as OS/2 for PowerPC, much easier.
TIP: Display a device driver header from the kernel debugger. The device driver header is always at the start of the device driver's first data segment. The device driver's header contains the device name, the code and data segment selectors, the IDC entry point address and a pointer to the next device driver header.
TECHNIQUE: To display the device driver header, enter .d dev ds:0 at the debugger command prompt. The kernel debugger displays the device driver's header with text strings defining each field. An example:
##.d dev ds:0 DevNext: 06f0:ffff DevAttr: 8940 DevStrat:0000 DevInt: 0000 DevName: TESTCFG$ DevProtCS: 06f8 DevProtDS: 06f0 DevRealCS: 0000 DevRealDS: 0000
LAN Server Tips:
TIP: If your application needs to run on LAN Server 3.0, use INCL_32 and the 16-bit API entry points instead of the new PURE_32 entry points. The 32-bit entry points don't exist on 3.0 machines. They can, however, be called on a 4.0 client against a remote 3.0 server.
TIP: When you issue a GetInfo or Enum API, don't call it with a 0 length buffer to see how big a buffer is required. Allocate a 4KB buffer, instead, and allocate a bigger buffer and call it again if the first buffer isn't big enough. Nine times out of ten, 4KB will be big enough for the returned data, and getting the information in one call instead of two is a worthwhile savings, particularly when the call is a remote API.
Workplace Shell Tips:
TIP: Make sure that your application does not prevent the Workplace Shell from shutting down normally.
TECHNIQUE: A well designed Presentation Manager application will, as you know, involve multiple threads. If some of your secondary threads have created a message queue by calling WinCreateMsgQueue in order that they can send messages, then it is important that they also call WinCancelShutdown(hmq,TRUE).
The reason is that when the system is processing a shutdown request, it picks one message queue per PM process to post a WM_QUIT message to, and expects that message queue to respond to the WM_QUIT by having all threads in that process terminate. If the message queue that the system selects is not expecting to receive the WM_QUIT, then shut down will not complete. By calling WinCancelShutdown, you are telling the system that your secondary thread is not prepared to handle a WM_QUIT request.
TIP: Make sure that your Workplace Shell subclass's DLL is properly loaded and unloaded.
TECHNIQUE: If your class is prevented from loading/unloading properly you might have problems replacing your DLL, or creating objects of your subclass after your class is unregistered. In most cases, the problem is that your DLL is still in use by the system, and was not unloaded, even though your SOM class may have been unregistered by the Workplace Shell. If your application does any of the following, you will have problems loading/unloading your class:
- You have called DosLoadModule explicity, and have not called DosFreeModule an equal number of times.
- You have called DosExitList to register an exit list, and the system cannot unload your DLL because the exit list is still registered.
- Your DLL exports entry points that are imported by another DLL, and that DLL is still in use by the Workplace process.
- Your class data is placed in a shared segment via your .DEF file, rather than in an per process segment, which is the normal default, and your DLL is loaded by any other process in the system.
- You have called WinSetHook to register a hook procedure in your DLL.
- Your DLL is in the .INI file system load list
- Your class implements the _wpclsQueryInstanceType or the _wpclsQueryInstanceFilter methods.
TIP: Implement exception handling on any threads that you create to run on the Workplace process. Otherwise, when your application traps, the Workplace Shell will "collapse" and not handle your trap gracefully.
TECHNIQUE: To prevent this, use DosSetExceptionHandler and DosUnsetExceptionHandler in your thread, and handle any exceptions by recovering, or terminating just your thread. The system default exception handling will terminate the process. For a very good discussion of exception handling on OS/2 threads, see the article by Monte Copeland in The Developer Connection News, Volume 2 (that is provided on the accompanying Developer Connection for OS/2 CD-ROM).
TIP: Exert control over whether or not your class will be unregistered by the Workplace Shell.
TECHNIQUE: Some applications never want their classes/DLLs to be unloaded. If not, you can prevent your class from being unregistered, or going "dormant" by creating an object of your class in the NOWHERE folder. Or, better yet, you can use the _wpclsIncUsage method, which is now available to applications developed for the newest OS/2 beta (Beta 2), which is on the accompanying Developer Connection CD-ROM. By the way, a lot of new methods are made available with the Beta 2.
TIP: Make sure that if you use your own containers to hold WPObjects that the Workplace Shell will recognize your window hierarchy.
TECHNIQUE: Objects are officially "inserted" into containers by invoking the _wpCnrInsertObject method on each object. So remember, the Workplace Shell:
- Subclasses the owner of a container when you first call _wpCnrInsertObject, or _wpRegisterView. The Workplace Shell then intercepts many of the container messages in order to make the mini records inserted in your container work like objects.
- Expects there to be a one-to-one correspondence between the owner of the container and the container control itself.
- Expects that the ID of the container control is FID_CLIENT.
If you have two containers on a dialog into which objects are inserted via _wpCnrInsertObject, you may need to artificially extend your window hierarchy. This will ensure that the Workplace Shell sends the proper notifications to the correct container owner (according to the assumptions listed above).
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation