Eric Fogelin, David Wood, and Noel Bergman
Porting applications from the Microsoft WindowsÔ graphical environment to OS/2 Presentation Manager (hereafter "PM") has just become much simpler. Microsoft has created a set of software tools, called the Microsoft Windows to OS/2 Software Migration Kit (SMK), which acts as an extension to the Microsoft Windows Software Development Kit Version 3.0 (SDK). The SMK reduces the conversion time for a typical large application from months to days, by supplying a mapping layer that translates Windows1 function calls into OS/2 function calls.
This code layer, implemented as a set of OS/2 dynamic-link libraries (DLLs), sits between PM and the Windows application, translating calls to the Windows API at run time. When the Windows application calls an API function to draw a line, for example, the mapping layer accepts the Windows API call, interprets it, reorders and converts the parameters, and calls the corresponding PM API (see Figure 1). Converted SMK applications run as 16-bit OS/2 executables on Versions 1.2 and higher, and 2.x.
Developers convert their Windows applications by relinking with a new set of libraries. Although to the user converted SMK applications appear as PM applications (see Figure 2), they behave internally as if they were running under Windows. SMK applications are OS/2 processes, so they receive many of the benefits of PM, including the ability to exchange data with other PM applications via the Clipboard, dynamic data exchange (DDE), or interprocess communication (IPC). You can enhance SMK applications with additional code that takes advantage of specific OS/2 functionality, such as multiple threads, and High Performance File System (HPFS) features, such as long filenames and extended attributes (EAs).
A beta release of the SMK should be available to qualified developers shortly after press time, with a final release to follow several months later.
SMK Contents and Installation
The SMK includes several conversion utilities, import and C run-time libraries for four memory models (small, medium, compact, and large), debug and retail versions of the mapping DLLs, PM-compatible Windows fonts, an SMK version of Windows Help, on-line documentation, and sample source code. Figure 3 lists the SMK contents.
The SMK SETUP and SMK tools are all bound applications so they can be run under DOS2 or OS/2 development environments. But since the migrated applications run only under OS/23, testing and debugging must be performed in OS/2 Version 1.2 or later using a protected-mode debugger. In addition to OS/2, you will need the Windows SDK 3.0 and Microsoft C Version 5.1 or 6.0. The Microsoft OS/2 Presentation Manager Toolkit Version 1.2 is not necessary for the conversion, unless you plan to enhance your SMK application with OS/2-specific features.
SETUP is similar to the Windows SDK installer. It copies the SMK tools and samples, and builds only the memory model C run-time libraries you request, thus saving disk space. If you need more memory model libraries later, you can rerun SETUP without reinstalling the entire SMK.
After you install the SMK, you must update the system environment variables used to build the Windows
application (such as LIB and PATH) so that both the SMK and SDK are referenced. The SMK relies on SDK tools such as the resource compiler. You should rebuild the SMK samples to verify that the SMK and environment are correctly set up.
If applications that are converted and tested under the beta SMK meet your standards of performance and reliability, you can ship your converted product accompanied with the beta version of the SMK DLLs. To ensure that the final release of the SMK DLLs does not affect ISVs that have shipped using the beta SMK, the DLLs have release-specific names. The SMK's beta DLLs have names with a _B suffix, such as: GDI_B.DLL, USER_B.DLL, and KERNEL_B.DLL. DLLs in the final release will have suffixes other than _B. It is recommended that all SMK DLLs be installed in the C:\OS2\DLL directory of
OS/2. That way multiple SMK applications share a single set of the DLLs. This is not a requirement; the only requirement is that the DLLs are in a directory pointed to by the OS/2 LIBPATH environment variable.
SMK Conversion Process
Successful conversion of a Windows application using the SMK requires that the application is Windows 3.0-compliant and runs in protected mode. As in the Windows SDK, there are memory-model-dependent C run-time libraries but only one memory-model-independent import library, LIBMK_B.LIB. This import library contains all the Windows API imports to the SMK mapping layer DLLs. SMK-specific library names are used so as not to conflict with existing Windows libraries. To convert library names in your make files, the following SMK naming convention is used:
Windows SMK
LIBW.LIB LIBMK_B.LIB
xLIBCyW.LIB xLIBCyMK.LIB
xDLLCyW.LIB xDLLCyMK.LIB
x is the memory model (S, M, C or L) and y represents emulator or alternate math support (E or A)
In addition to the SMK libraries, the OS/2 import library, OS2.LIB, is required since an OS/2 application is being created. OS2.LIB is shipped with the SMK.
One of the most time-consuming tasks when performing a traditional port of a Windows application to OS/2 is converting the resource files, containing dialog boxes, menus, bitmaps, and so on, because Windows and OS/2 have incompatible resource definitions. SMK applications retain their Windows resources and the Windows resource compiler is still used to bind these resources to the SMK executable. The SMK mapping layer loads and manages the Windows resources.
A subtle problem occurs when the SMK applications are displayed by the OS/2 Program Manager: it searches for an icon in the executable to display but recognizes only the PM icon format. Because the converted application's icon is still in Windows format, it always uses the unexciting default PM icon.
The SMK comes with three utilities to resolve this problem. CONVICON converts a Windows 3.0 icon to
OS/2 format. RCSMK spawns an SMK version of the
OS/2 resource compiler (RCPM) to bind the PM icon to the SMK executable before the Windows resource compiler binds the Windows resources. The OS/2 Program Manager thus finds a PM icon to display and the SMK mapping layer knows to skip the PM icon when accessing the Windows resources. Figure 4 shows a series of Windows 3.0 applications displayed by the Windows 3.0 Program Manager and the SMK versions with converted PM icons displayed by the OS/2 Program Manager.
Windows and OS/2 font file format differences make a font converter necessary. CONVFONT.EXE converts Windows font files into OS/2-compatible font files. The SMK also provides several fonts used in Windows that are not present in OS/2. WINMONO.FON, WINPRO.FON, and SYMBOL.FON must be installed via the OS/2 Control Panel as are any additional ISV fonts converted using CONVFONT.EXE.
The SMK includes a version of the Windows Help Manager that has itself been converted via the SMK to operate under OS/2. As long as the Help Manager is in the path, spawning and interaction occur via the normal Windows help functions. To use WinHelp, you must ship a copy of WINHELP.EXE with your product. Your setup program should install it along with your application.
Sample Conversion
To prove how easy it is to convert Windows applications using the SMK, Windows code from a recent MSJ article ("A New Multiple Document Interface API Simplifies MDI Application Development," Vol. 5, No. 4) was converted. MDIDEMO was written to illustrate the Windows 3.0 MDI support. A native port of this application would have required significant source code changes. Using the SMK, however, requires no source code changes, only minor changes to the MDIDEMO.MAK make file to reference the SMK libraries (see Figure 5).
As you can see, only the library names have changed. You must use the /nod linker switch when specifying the SMK libraries. If you don't, the linker will do a default library search and find the Windows libraries first. The compiler command-line switches are the same. Because MDIDEMO uses Windows resources, the Windows resource compiler is used to compile and bind MDIDEMO.RC to the executable.
MDIDEMO did not originally have an icon. For the sake of illustration, a Windows icon was created to demonstrate the SMK utilities CONVICON and RCSMK. The make file in Figure 6 runs these utilities to convert the Window icon to PM format and bind this PM icon resource to the executable, so that the icon will appear in an OS/2 Program Manager group. (This and other sample SMK-converted applications and the DLLs needed to run them under OS/2 may be downloaded from any MSJ bulletin board.)
Figure 7 shows MDIDEMO running on Windows 3.0 and OS/2 1.2. Without any source code changes, the Windows program successfully runs on OS/2 with equivalent functionality and MDI support. (Differences in the contents of the Rectangles child windows is due to MDIDEMO itself, which repeatedly creates random rectangles.)
Architecture
Because an SMK-converted application operates as if it's running under Windows, while looking like a PM application, it might seem that the SMK application has limited participation in the PM environment. However, the mapping layer allows converted applications to interact with other SMK and PM applications automatically. Converted applications and native PM applications have full Clipboard data transfer capability, including two-way metafile conversion between the Windows and PM metafile formats. The DDE message protocol, which enables dynamic communication with other PM applications, is also supported. The mapping layer handles code page translation of DDE and Clipboard text. Unfortunately, Windows has additional Clipboard formats not present in OS/2. The mapping layer cannot translate private formats or formats unsupported in OS/2.
The mapping layer also resolves differences between Windows and OS/2 profile information storage. OS/2 uses the binary file OS2.INI for system configuration storage, while Windows uses a file named WIN.INI, which is in ASCII. Likewise, while both systems support private initialization files, OS/2 uses a binary format while Windows uses ASCII. Windows applications typically read and write configuration information with the functions GetProfileString, WriteProfileString, and GetProfileInt. The SMK intercepts these functions and maps system values (system colors, international country settings, fonts, and so on) to OS2.INI. All other values are assumed to be application-specific and are mapped to WIN.INI. The SMK searches the path for the first occurrence of WIN.INI. If WIN.INI does not exist along the path, the SMK creates it in the current directory.
Windows and OS/2 share architectural characteristics such as dynamic linking, resource management, and windowing that allow a converted application to run as a true OS/2 process rather than requiring virtualization. The mapping layer does not rely on support from the DOS compatibility box or the virtual 8086 mode of the 80386 processor. Because Windows and OS/2 use an EXE format known as the New Executable Format (new compared to DOS), the OS/2 loader knows how to handle code preloading and dynamic linking. Therefore, the mapping layer handles Windows function imports via standard OS/2 dynamic linking and translates the Windows functions into OS/2 equivalent operations at run time.
Many simple Windows functions are mapped directly to their OS/2 equivalents. A few that have no equivalents, such as the Windows sound functions, are simply stubbed out (see Figure 8). For most functions, the mapping layer retains context information across multiple Windows function calls. Window handles, window device contexts, and resources are managed by the mapping layer such that the relinked application behaves as if running under Windows. An interesting aspect of the mapping layer is that it creates and handles proxy window handles for all PM windows that an SMK application interacts with. For example, if an SMK application calls GetFocus while a PM window currently has the focus, a unique non-PM window handle that represents the PM window is returned to the SMK application.
Handles to objects such as windows, bitmaps, and device contexts are not interchangeable between PM and SMK applications. These handles must be converted by the mapping layer during calls from the SMK application to the Windows API. Messages between SMK and PM applications are similarly manipulated by the mapping layer.
The SMK must also contend with differences between Windows and OS/2 multitasking. OS/2 offers preemptive multitasking, in contrast to the cooperative, nonpreemptive, message-driven multitasking of Windows. Windows applications relinquish control of the CPU only when they call GetMessage or PeekMessage. This application-controlled "baton-passing" allows Windows applications to ignore certain synchronization and resource conflicts that can occur in a preemptive multitasking system such as OS/2.
Resource manipulation in shared DLLs illustrate the problems of bringing Windows applications to preemptive OS/2. If a routine in a shared DLL manipulates a resource but reaches the end of its time slice before completing the operation, another process may execute the same DLL routine and stumble upon a corrupt or partially manipulated resource. Windows DLLs do not guard against this scenario because under Windows, all DLL operations are atomic until a message queue is checked.
While a Windows DLL could be rewritten to use semaphores, the SMK mapping layer simplifies the process. The mapping layer duplicates Windows behavior-it will preempt an SMK application to schedule another SMK application only when the applications check their message queues via calls to GetMessage or PeekMessage. This synchronization of SMK threads does not affect native PM and OS/2 kernel threads.
The SMK mapping layer cannot support some features of OS/2 due to architectural differences between Windows and OS/2 and how they exploit the 80x86 architecture. Under Windows protected and 386 enhanced mode, all Windows applications share one Local Descriptor Table (LDT). Each OS/2 process has a private LDT. Though it has been discouraged, some Windows applications may take advantage of the current LDT usage of Windows to support direct manipulation of another application's data.
As an example, a Windows application that is designed to subclass another application's windows operates as intended under Windows 3.0, but must be redesigned if converted via the SMK to run on OS/2. Subclassing another application's windows is generally not supported under OS/2 and providing this functionality is outside the scope of this article. Windows hooks are supported under the SMK, though there are similar issues to those raised in subclassing. Hook procedures must reside in DLLs and the system will do an implicit LoadModule when the hook must be called from a different process.
The SMK supports the Windows global shared memory mechanism, GMEM_DDESHARE. The mapping layer translates global memory requests to DosAllocSeg or DosAllocHuge transparently, granting access to this shared memory to other processes via DosGiveSeg and DosGetSeg.
In addition to relying on different LDT designs, Windows and OS/2 also implement different ring architectures. All Windows applications and the Windows system run in Ring 1. OS/2 applications (including SMK applications) run at Ring 3, with the ability to create Ring 2 segments for executing port I/O. This causes problems when porting device drivers that cannot be addressed by the SMK. This is discussed further in the next section.
Windows applications often use their own DLLs that are shipped with the product. Obviously, these DLLs must be converted; the SMK provides DLL-specific C run-time libraries to do so. OS/2 loads these SMK DLLs just like any other OS/2 DLL, creating a problem that cannot be addressed directly by the mapping layer. Windows and OS/2 DLLs typically rely on an assembler start-up module, which contains its entry point. LIBENTRY.ASM, included in the Windows 3.0 SDK, is used by most Windows developers. The Windows and OS/2 loaders call the DLL entry points with a different set of initialized registers. For example, in Windows the CX register contains the DLL heap size specified in the DEF file; in OS/2, the SI register contains this information. Other registers are similarly affected.
An SMK tool, CONVDLL.EXE, modifies the DLL start-up code such that the standard Windows register set is restored. CONVDLL relies on a small source code change that must be inserted manually into LIBENTRY.ASM. CONVDLL.INC is a small include file containing the necessary signature information. The following illustrates the necessary code change to LIBENTRY.ASM.
cProc LibEntry, <PUBLIC,FAR>; entry point into DLL
INCLUDE CONVDLL.INC
cBegin
push di ; handle of the module instance
push ds ; library data segment
push cx ; heap size
push es ; command line segment
push si ; command line offset
o
o
o
The CONVDLL changes also assure that the SMK DLLs are properly initialized. In this way, Windows APIs may be called in LIBENTRY.ASM. Without CONVDLL, you could not be sure that the SMK DLLs are initialized during LIBENTRY execution. The SMK includes sample code illustrating the use of CONVDLL.
SMK Limitations
Most Windows API functions are supported in the SMK mapping layer, with the exception of sound, 32-bit memory management, some Graphic Device Interface (GDI) functions, and a few other functions (see Figure 8). These functions must be converted differently. Applications that call DOS system interrupts directly (such as INT 21H) should use the Windows 3.0 Dos3Call function for equivalent interrupt-level support. A list of supported DOS system interrupts can be found in the SMK
documentation.
Windows supports several types of device drivers (DOS, Windows, GDI) that are not supported by the SMK mapping layer. A Windows application that relies on a DOS device driver loaded via CONFIG.SYS or a TSR must use an OS/2 equivalent (many such drivers already exist). If one doesn't exist, it must be developed using the OS/2 Device Driver Kit.
The SMK uses PM display and printer drivers for output. The mapping layer compensates for differences in the Windows and PM drivers, especially in printer escape support, but relies on PM drivers for actual output. PM does not support as many devices as Windows, but does cover the most popular displays (CGA, EGA, VGA, 8514/A, and so on) and printers (PostScript, Hewlett-Packard LaserJet series, Epson, and so on). The SMK handles the proper implicit mapping between these standard device drivers so that they function as if they were the actual Windows drivers. The mapping occurs as a result of normal API calls and does not include direct communication with devices via port I/O, interrupts, or memory mapped I/O.
The differences between Windows and OS/2 ring architecture make it impossible to perform direct port I/O from a Windows application. Port I/O can be implemented in an OS/2 Ring 2 IOPL segment, but this requires source code modification and segregation of I/O calls to a separate code segment. It is also impossible to place interrupt service routines within DLLs as in Windows. Interrupts can be handled only at Ring 0 in a device driver under OS/2.
Converted applications run 5 to 10 percent slower than native PM applications, because of the time required for the mapping layer to execute. In general, they also perform 5 to 15 percent slower than the original applications running in native Windows protected mode, depending upon the actions performed. SMK application load time and dialog box performance may appear slower at times due to the mapping overhead. The mapping layer must be loaded when an SMK application is first started, so total load time is longer. Intensely repetitive graphic operations involving creating and freeing Windows Device Contexts (DCs) also slow performance. On the other hand, running in OS/2 with HPFS greatly enhances file I/O operations.
Advanced SMK Use
Because an SMK application is an OS/2 process, it can take advantage of OS/2 features not found in Windows such as threads, long filenames, EAs, and IPC. Adding OS/2 features creates a hybrid application that may be difficult to support in future OS/2 releases. You should add
OS/2 features only where
appropriate.
Threads are particularly useful when long calculations are involved, such as recalculating a spreadsheet; where there is a need to block for an indefinite period of time for a specific event, like blocking on a semaphore used for IPC; or when large amounts of information must be transferred, such as during large file manipulation or serial data exchange.
Threading is affected by the mapping layer's synchronization of SMK threads. Only one SMK thread making Windows API calls can be called at a time. Therefore, no Windows APIs can be called in secondary threads; only
OS/2 API functions such as DosCreateThread, DosOpen, DosRead, and DosAllocSeg can be called. The current SMK libraries cannot support a multiple-threaded C run-time. Secondary threads calling C run-time functions could corrupt buffers relied on by other application threads calling related C run-time functions. Applications that require full multithreaded C run-time support should use a separate OS/2 DLL (created via LLIBCDLL.LIB) or an OS/2 daemon process. If a daemon process is used, shared memory, pipes, or other IPC mechanisms can be used to communicate between the worker (daemon) process and the user interface (SMK application).
There is one exception to the rule that Windows API calls cannot be made from secondary threads. PostMessage may be used in secondary threads as an asynchronous notification mechanism for the background thread to inform the primary SMK thread that an operation has completed. The main SMK thread can also poll background threads for status information. If global variables or shared memory or both are used to communicate between the SMK thread and background threads, critical sections and semaphores should be employed. The primary SMK thread should not block on a semaphore indefinitely or fail to check its message queue often. If it does, other SMK applications will not be scheduled and will receive no CPU time. This is as important for SMK applications as it is for native Windows applications.
You may want your converted application to handle long filenames. A common problem in Windows is allocating filename buffers just large enough to hold FAT 8.3 filenames and path buffers just large enough to hold the maximum 64-character path length. When using HPFS, however, you can use the OS/2 function DosQSysInfo to determine the maximum length of a pathname in the current system and allocate your file and path buffers accordingly.
If your application includes filename parsing code that depends on the 8.3 format, you should modify the code so that it can handle long filenames-specifically, filenames that contain embedded spaces and multiple dot delimiters. The Microsoft OS/2 Presentation Manager Toolkit fully documents parsing rules as well as other HPFS issues. Once the necessary buffer and parsing changes have been made, simply mark your application as being long-filename-aware by adding the LONGNAMES descriptor to the DEF file. The SMK mapping layer is already long-filename-aware. Once marked, OS/2 will pass long filenames to your application. For example, DlgDirList will now display full 256-character filenames in its list box when the SMK application is marked and run under
OS/2. Sample code included with the SMK illustrates long filename and extended attribute manipulation in a modified Windows application.
Conclusion
The SMK enables Windows software developers to address the OS/2 platform by leveraging their existing Windows development efforts. The SMK conversion process is faster and easier than a native port, and is often as simple as a relink with the SMK libraries.
No license fees are required to ship converted applications. You simply include the SMK DLLs with your application. The Windows Help engine (WINHELP.EXE) may also be shipped along with the SMK application, if required. Windows applications converted to OS/2 using the SMK should continue to run on OS/2 2.0 and above, because 2.0 is planned to be compatible with previous
OS/2 releases.
1For ease of reading, "Windows" refers to the Microsoft Windows graphical environment. "Windows" refers only to this Microsoft product and is not intended to refer to such products generally.
2As used herein, "DOS" refers to the MS-DOS and PC-DOS operating systems.
3As used herein, "OS/2" refers to the OS/2 operating system jointly developed by IBM and Microsoft.
Figure 3. Beta SMK Contents
SETUP.CMD Setup (OS/2)
SETUP.BAT Setup (DOS)
SETUP.DAT Setup (data file)
README.TXT General information, release notes
PACKING.LST Disk contents description
SMK.HLP SMK manual in on-line Advisor format Conversion Tools CONVFONT.EXE Windows to PM font file converter
CONVICON.EXE Windows to PM icon (.ICO) converter
CONVDLL.EXE Windows DLL conversion utility
CONVDLL.INC Include file for Windows DLL conversion
RCSMK.EXE SMK-specific resource compiler
RCPM.EXE OS/2 PM 1.2 resource compiler
WINHELP.EXE SMK Windows help engine (English) Converted Windows Fonts WINMONO.FON Windows fixed pitch font
WINPRO.FON Windows dialog box system font (small)
SYMBOL.FON Windows symbol font Substitute Windows Libraries BUILDLIB.CMD SMK library create tool (OS/2)
BUILDLIB.BAT SMK library create tool (DOS)
LIBMK_B.LIB General import LIB (replaces LIBW.LIB)
OS2.LIB OS/2 import LIB NOTE: The following files are created during the SMK install process. xLIBCyMK.LIB Replaces xLIBCyW.LIB
xDLLCyMK.LIB Replaces xDLLCyW.LIB NOTE: x = model (S, M, L, C) y = math package (E or A) SMK Mapping Layer DLLs (debug and retail) USER_B.DLL USER
KERNEL_B.DLL KERNEL
GDI_B.DLL GDI
PMSMK_B.DLL (SMK only) Windows-equivalent DLLs
PMMETA_B.DLL (SMK only)
SOUND_B.DLL SOUND
KEYB_B.DLL KEYBOARD
W87EM_B.DLL WIN87EM
SYSTEM_B.DLL SYSTEM *.SYM Symbol files for debug versions of all DLL files Converted Windows Sample Applications MAKEALL.CMD Batch file to build all samples (OS/2)
MAKEALL.BAT Batch file to build all samples (DOS) \GENERIC Basic Win 3.0 example
\REVERSI Advanced Win 3.0 example (contains sample help file: REVERSI.HLP)
\WINDLL How to convert a Win DLL
\OS2DLL How to add an OS/2 DLL
\EDITFILE Long filenames and EAs
\CLOCK Dos3Call example
Figure 5. Make File Conversion
Original MDIDEMO.MAK
#-----------------------
# MDIDEMO.MAK make file
#-----------------------
mdidemo.exe : mdidemo.obj mdidemo.def mdidemo.res
link mdidemo, /align:16, NUL, /nod slibcew libw, mdidemo
rc mdidemo.res
mdidemo.obj : mdidemo.c mdidemo.h
cl -c -Gsw -Ow -W2 -Zp mdidemo.c
mdidemo.res : mdidemo.rc mdidemo.h
rc -r mdidemo.rc
The SMK version of MDIDEMO.MAK
#-------------------------------------
# SMK version of MDIDEMO.MAK make file
#-------------------------------------
mdidemo.exe : mdidemo.obj mdidemo.def mdidemo.res
link mdidemo, /align:16, NUL, /nod slibcemk libmk_b os2, mdidemo
rc mdidemo.res
mdidemo.obj : mdidemo.c mdidemo.h
cl -c -Gsw -Ow -W2 -Zp mdidemo.c
mdidemo.res : mdidemo.rc mdidemo.h
rc -r mdidemo.rc
Figure 6. Make File with Icon Conversion
#---------------------------------------
# RCSMK version of MDIDEMO.MAK make file
#---------------------------------------
mdidemo.exe : mdidemo.obj mdidemo.def mdidemo.res mdiicon.res
link mdidemo, /align:16, NUL, /nod slibcemk libmk_b os2, mdidemo
rcsmk -PM mdiicon.res mdidemo.res
mdiicon.res: mdidemo.ico
convicon mdidemo.ico mdiicon
mdidemo.obj : mdidemo.c mdidemo.h
cl -c -Gsw -Ow -W2 -Zp mdidemo.c
mdidemo.res : mdidemo.rc mdidemo.h
rc -r mdidemo.rc
Figure 8. Windows Functions Unsupported in SMK User GetKeyboardState
IconSize
MenuItemState
SetKeyboardState
SetMenuItemBitmaps
TrackPopupMenu Kernel AllocSelector
FreeSelector
GetCodeHandle
GetCodeInfo
GetCurrentPDB
ValidateFreeSpaces
LimitEmsPages 32-bit Memory Management GetWinMem32Version
Global16PointerAlloc
Global16PointerFree
Global32Alloc
Global32CodeAlias
Global32CodeAliasFree
Global32Free
Global32Realloc GDI Palette Management
AnimatePalette
CreatePalette
GetPaletteEntries
GetNearestPaletteIndex
RealizePalette
ResizePalette
SelectPalette
SetPaletteEntries
UpdateColors
Region
CreateEllipticRgn
CreateEllipticRgnIndirect
CreatePolyPolygonRgn
CreatePolygonRgn
CreateRoundRectRgn
Bitmap ExtFloodFill
FloodFill
Text GetTextCharacterExtra
SetTextCharacterExtra
SetTextJustification Keyboard (Limited SMK support) GetKBCodePage
GetKeyboardType
GetKeyNameText
MapVirtualKey
OEMKeyScan
SetSpeed
ToAscii
VkKeyScan All Sound APIs