Daniel Wilson's repost of Steve Loughran's WinAPI FAQ


Original Source (if still available)

Right after ... Books for Win32 Programming

Buy at Amazon! Dan Appleman's Visual Basic Programmer's Guide to the Win32 API Buy at Amazon! Charles Petzold's Programming Windows, The Definitive Guide to the Win32 API using C/C++ Buy at Amazon! Jerry Lozano's The Windows 2000 Device Driver Book: A Programmer's Guide

Frequently Asked Questions about Win32 Programming

Revision 3.08

Welcome to Steve Loughran's utterly unofficial and sporadically accurate list of frequently asked questions about the Win32 API. This document covers common issues raised in the comp.os.ms-windows.programmer.win32 USENET group. It also covers lots of the hard questions that colleagues come up and ask me, and things that have caused much hair pulling as project deadlines approached.

Warning: This document is probably out of date by the time you read this, as are most other Windows programming documents on Web. The reason for this is simple: programmers are always too busy getting programs to work to worry about keeping the documentation to date.
1 Introduction: Win32
2 Getting Started
3 Development Tools
4 Win32 Platforms
5 Programming Questions
6 Internet Programming
7 DLLs: Dynamic Linked Libraries
8 Console Mode Applications
9 Services
10 Help! My Program does not Compile and Link!
11 Debugging -or 'help, my program doesn’t work'
12 Shipping -or 'help, my customers say my program doesn't work'
13 Miscellany

1. Introduction: Win32

1.1 What is Win32?
1.2 What is the Win32 API?
1.3 How does it differ from the Win16 API?
1.4 Why should I port my code to 32 bits?
1.5 Why shouldn't I port my code to 32 bits?
1.6 Can I write programs using NT's Posix API?
1.7 What is the history of the Win32 API?

1.1. What is Win32?

Win32 really refers to the "Microsoft(r) 32 bit Windows(tm) API", the Win32 API, . "Win32 Applications" are programs which are built with the Win32 API. Computers running operating systems capable of executing Win32 Applications are referred to as Win32 platforms.
[Top of Section] [Index]

1.2. What is the Win32 API?

It is the 32 bit successor of the Win16 API: the Application Programming Interface which has been used for writing Windows programs since version 1.0. It is the combination of data types, definition and functions which C programmers include as a set of header files. Most of the functions are implemented in DLLs, to which applications link at run time -either directly or through COM interfaces.

The core API divides into three sections:

Each is pretty much built on top of the other. In Windows 95 the services are provided by three DLLs -USER32, KERNEL32 and GDI32, which either implement the calls or pass them down to their 16 bit predecessors. In Windows NT many of the services are implemented in Kernel Mode and various forms of inter-process communication are used to manage this.

To C++ programmers this is known as "the raw API" as opposed to the API functions which are wrapped up by C++ classes. Beginners quite often have an unexplained fear of using this API, as though you shouldn't have to use it in an MFC or OWL program. This is not true: the C++ classes are there to provide a framework for applications, but the raw API covers a lot more functionality.

As well as the base "Platform API", the Win32 API has grown to provide many more features and function calls, from the games and entertainment related DirectX APIs to the high throughput networking and service related calls used on NT servers to provide minicomputer and mainframe like performance in commercial systems.
[Top of Section] [Index]

1.3. How does it differ from the Win16 API?


[Top of Section] [Index]

1.4. Why should I port my code to 32 bits?

When starting out coding a new program, it is far easier to write a pure 32 bit app than old 16 bit programs -even if you used to use the large model. For working 16 bit apps there are a lot of benefits to be gained by porting to 32 bits:-

In April 1997 it was estimated that there were 60 Million Win95 systems, increasing at 4M units/month, an 3 Million NT systems increasing at 300K units/month (source: Microsoft at WinHec). By September 1997 it was estimated that there were 100 Million Win32 systems, out of a total of 200 Million Windows platforms. There is clearly still merit and profit in supporting Win31. This can be done -sort of- with Win32s.
[Top of Section] [Index]

1.5. Why shouldn't I port my code to 32 bits?

If you choose not to upgrade your application to Win32, then you can still stamp the exe as requiring Windows 4.0, so that the OS will automatically clean up all resources it has allocated.
[Top of Section] [Index]

1.6. Can I write programs using NT's Posix API?

Don't even bother trying to use this. It's the bare minimum of Posix compliance and doesn't offer much functionality. For example, there is no sockets support or integration with the real Win32 API. It's only there to help NT win sales in tenders where Posix support is mandatory (i.e. governments)

The win32 console API is close enough to Posix functionality that many Posix apps should be compilable within the win32 subsystem -this is what the Gnu/win32 project is trying to support.
[Top of Section] [Index]

1.7. What is the history of the Win32 API?

This is a fairly long story, which is partially documented in an appendix
[Top of Section] [Index]

2. Getting Started

This sections answers questions important to anyone just starting to program for win32.
2.1 How do I write Win32 programs?
2.2 What is a suitable computer?
2.3 What is a suitable development tool?
2.4 What OS should I use?
2.5 Do I need the Win32 'Platform' SDK?
2.6 What important things should a newbie learn?
2.7 Are there any on line introductions to Windows programming?
2.8 Do I need MFC to write an application?
2.9 Are there alternative C++ class libraries to MFC?
2.10 How do I migrate from Unix?

2.1. How do I write Win32 programs?

  1. Get a suitable computer.
  2. Get a suitable development environment.
  3. Get a decent book or two. Read them. And ideally an MSDN subscription
  4. Start writing Win32 programs, keeping those books handy
  5. Don't give up when things don’t work the way you intended.

[Top of Section] [Index]

2.2. What is a suitable computer?

Ideally, the fastest box with the most memory and hard disk you can afford. However, if you already have bought a PC in the last two or three years, then it should be up to the task. One purchase that will probably be required is extra RAM: 64 MB is realistically the bare minimum for development -and 128 MB preferable. With only 48 Mb or less you will find that a PII system compiles no faster than a '486, as it will be continually swapping to hard disk. Above 256 MB compiler performance seems to top out, but the box takes ages to reboot.

Other desirable features of a development PC are -in approximate order of desirability

Having a backup solution and process is also considered pretty important. DAT and Tape drives are good for this; Zip are drives only so-so. CD-RW is pretty coo.

For team development a team server with shared directories, web server (integrated with the shared directories) and source code management system is great for development and delivery. NT server or a Linux box with Samba both fit in here. Either way, this should really be a separate system from any server you are testing code on.

Anyone doing device driver work will need one -maybe two- target PCs.

The issue of a development PC is covered in more depth in a separate article.
[Top of Section] [Index]

2.3. What is a suitable development tool?

Any environment which can link to the Win32 API libraries to execute code you have written can be used to develop Win32 programs.

This includes not just the classic programmer tools of assemblers and C/C++ compilers, but rapid application development environments such as Visual Basic and Delphi, Database systems such as Access and many "office" applications which have been enhanced with programming languages.

Some versions of the Java programming language -specifically Microsoft J++- can also be used for Win32 programming.

Many of the RAD tools simplify programming by hiding the API, making it rather tortuous to perform some relatively simple tasks. This means that most serious Win32 coding is done in the classic programmer languages of C and C++, and to a lesser extent in x86 assembly or the Delphi variant of Pascal.
[Top of Section] [Index]

2.4. What OS should I use?

This is mainly a matter of personal choice.

Windows NT is excellent for development, mainly because it is so robust and you can still use other applications during compiles. It does use a fair bit of RAM, even before you add the compiler's requirements. Developing 16 bit apps in NT is good too, simply because you can reboot the 16 bit subsystem so easily.

Windows 9x is not quite as robust as NT, but it runs better on a lower-end machine. If you want to use libraries for which there are no current NT equivalents then win9x is a must. [Or cheat and have two computers]. As more "consumer-class" functionality is added to NT the need for using win9x is lessening

Likewise, NT offers many features which are not available in Win95.

Win31 and Win32s is not really suited for application development. Borland C++ certainly can be used in this situation, but not Visual C++. Consider relegating this platform to a test environment if a Win32s version is required.

Windows CE is currently only a target platform, and not one to run on your primary development PC.
[Top of Section] [Index]

2.5. Do I need the Win32 'Platform' SDK?

Not necessarily, because your compiler should be sufficient. The SDK contains the header files and import libraries for the latest version of the API, along with samples and useful debugging and stress tools. So it is worthwhile if you have the spare bandwidth and disk space. You can download this 20+MB "Platform SDK" off the Microsoft Web site.
[Top of Section] [Index]

2.6. What important things should a newbie learn?

  1. The class libraries are only a foundation: there is nothing wrong in using the raw Win32 API.
  2. Use the on-line help. Everyone else does.
  3. Learn to write 32 bit applications without bothering to serve a 16 bit apprenticeship. And ignore dated books which cover 16 bit programming: there are some things programmers were not meant to know.
  4. Look through the sample programs your compiler ships with: they are a good way of learning how to write windows applications and a source of code.
  5. Resource files (.RC) are really text files and sometimes are best edited as such instead of with a resource editor.
  6. Step into the source of the class libraries when debugging to find out what's really happening, but avoid modifying the source or making big assumptions about the implementation unless you have to -either of these tricks increase your maintenance costs. If you do have to modify the class libraries, cutting and pasting the source into your own classes first is usually better.
  7. Sometimes there really are bugs in the OS, class libraries and compiler code generators. But usually, when a routine doesn't work the way you expected, the fault is yours. Either there is a defect in your code, or there is a defect in your assumptions. With experience, both of these situations will arise less often.
  8. Allow about six months to become reasonably competent, but never think you can stop learning.

[Top of Section] [Index]

2.7. Are there any on line introductions to Windows programming?

Yes, but they are not on a par with any printed documents. There is a simple reason for this: no-one makes much money from such on-line documents, so there is no incentive to either write them or get them technically correct, other than the appreciation of your peers. Some advertising funded sites are changing this, so things are getting better. Try entering for "Win32 Tutorial" into your favourite search engine to see what gets found. Also, there are lots of MSDN articles covering all aspects of Windows programming, from the introductory to the obscure.
[Top of Section] [Index]

2.8. Do I need MFC to write an application?

No you most certainly do not -you can still quite happily write a program in the 'raw API' -as much of the base OS and bundled appliccccations are. Everything you can do with MFC and/or ATL can be done in the raw API, the only issue being how much work is involved. [CS graduates call this concept "Turing Equivalence"]

The main justification for raw API code is usually size and performance -raw Win32 apps don't need MFC libraries, so can load faster and take up space. Anything intended primarily for background use -a little taskbar applet for example- should consider a raw implementation rather than MFC, which is a bit of overkill. For ActiveX controls downloaded from the net, download time is critical, and eliminating the need for MFC libraries helps there. With a really large program the gains of MFC are less clear -so much of the wheel gets reinvented that you end up with something almost as large but with worse documentation and more maintenance issues. You also lose all the performance gains the MFC code and the class wizards can deliver once you know how to make effective use of them.

Some things are very hard to write in raw Win32. OLE automation is a case in point, while database access needs a fair amount of support code whether the connectivity interface is ODCB, RDO, ADO or OLE DB. The ATL libraries are a halfway house -lighter weight than MFC, purer C++ than MFC, and utterly unreadable to the uninitiated. The STL (Standard Template Libraries) are also a good accessory to raw API and ATL coding, they give you the C++ standard string classes and semi decent vector and list structures. As for COM, if you use the "#import" pre-processor directive in VCC5 and up, the compiler makes COM calls in C++ workable, even for IDispatch derived interfaces.

Finally, if you do want to reinvent the wheel and build a better class library, go ahead. It is not impossible, just time consuming. Borland's OWL2.x library is still regarded by many as a better class library than MFC [this FAQ's author is one of them], and other people have done commercial class libraries (Metrowerks do a cross platform one, for example), or freeware (e.g. Sam Blackburn's WFC classes). An alternate trick is to write 'raw API' classes which can be used standalone or mixed in with MFC and ATL code, to fill in their gaps. For example a CDIBitmap class can provide bitmap access, while the core NT device hierarchy can be supported by a single header file's worth of classes with names like COSDevice, COSFile, COSSerialPort, COSWaitableTimer and so on. This lets you extend MFC where it is weak, yet not be tied to its use.
[Top of Section] [Index]

2.9. Are there alternative C++ class libraries to MFC?

Oh yes. As well as alternative commercial libraries from compiler vendors such as Borland and Metrowerks, there are also third party class libraries on sale.

However, one of the most valuable class libraries is free and comes in source form: Sam Blackburn's WFC class library . This library (as of release 39) includes a better XML parser than the IE5 one, and lots of really interesting goodies. It also provides an example of a) how a skilled programmer can build up a reusable library set to enhance their own productivity, and b) how a generous programmer can give away their work for the benefit of the entire community. Even if you choose not to use it, it can be used as a reference example of Win32 class library design and implementation.
[Top of Section] [Index]

2.10. How do I migrate from Unix?

Firstly, welcome to the dark side of software. You'll find that it isn't as bad as it's been made out, and pays quite well.

It's inevitable that when learning the Win32 API you will discover a lot of things that don't make a lot of sense. For example, why are there so many slightly different APIs -TextOut, ExTextOut and TabbedTextOut and PolyTextOut? Historical reasons. Likewise the split between NT Executive objects and all those other objects in a system: GDI objects, Windows and sockets. As the platform evolved, the API grew to match. Legacy support and a rapid evolution has been key strengths of Windows, and this shows in an API that from a Unix developer perspective is an incoherent mess. Well, too bad. It's like the x86 - an ugly duckling that has grown up into a successful, but still ugly, duck. Resistance, as they say is futile.

Migration Tips

There are various ISVs who support a Unix API on top of Windows, letting you support multiple platforms with a minimal amount of source divergence. In Cygnus and the CygWin Project have an open source product, and AT&T Research have a Unix library written under the guiding hand of David Korn.
[Top of Section] [Index]

3. Development Tools

This is a list of shipping products which can be used to generate Win32 code. This is also the section of the FAQ which dates the fastest, as many vendors update their products every 12-18 months, with bug fixes -"service packs"- available in the meantime.

Important Fact Number 1. No particular preference over development tools is being made here: purchase decisions need to made by individuals/groups based on their own needs, abilities, funds and long term plans.

Important Fact Number 2. There are no silver bullets in software engineering. Despite what the advertisments will tell you about application development at a click of a button, Windows programming requires skill, knowledge and hard work. Debug facilites and customer support can be as important as compilation speed or syntax highlighting.

As most products are available in "lite" editions, evaluating them all may cost time more than money. But it may prove a worthwhile investment.

NB: detailed but moderately opinionated product reviews are available nearby
3.1 Visual C++ /Visual Studio
3.2 Visual Basic
3.3 Borland/Inprise Delphi
3.4 Borland/Inprise C++5.x and C++ builder
3.5 Metrowerks CodeWarrior
3.6 Intel VTune
3.7 lcc-win32
3.8 Assemblers
3.9 Also Available
3.10 Watcom C++ 11
3.11 Microsoft Visual J++
3.12 Gnu for Win 32
3.13 Configuration Management Tools
3.14 What other tools are useful?
3.15 Books

3.1. Visual C++ /Visual Studio

A single integrated IDE which can be used for C/C++, Java and web page development. It's fairly heavyweight (64+MB RAM best) and hard on the disk drive , but very powerful.

The C and C++ compilers are probably the currently most popular compilers of these languages in the Win32 community. This means that many books and add-on tools focus exclusively on these tools. They are also invariably the first compilers to support new OS developments from Microsoft. Compilation speed and generated code performance are so-so, debugging facilities excellent once you get the hang of them.

One critique of these tools is that their development evolves for strategic reasons, rather than those of immediate benefit to the customers. For example the 32 bit IDE/compilers can not generate or debug 16 bit or DOS applications, and provide much more support for developing COM objects than displaying GIF and JPEG images. Likewise the Java tools may be great for 'DNA' use, but not for portable Java application development. But if you want to go where Wintel want to take you, these products can make the journey easier -especially if you prefer SQL server over Oracle.

Although single language options can be purchased separately, it may be cost effective to buy the complete set. A large hard disk is then obligatory. The Enterprise edition needs an even larger hard disk, but gives you a source code control tool (invaluable) and lots of back office integration toys (variable value). The amount of after sales support you get is still near zero.

Links: A more detailed review; the product's home page
[Top of Section] [Index]

3.2. Visual Basic

The successor to the 16 bit Visual Basic system. Comes with OCX equivalents of all the old VBXs which it used to ship with, plus a more OO language that adds classes but not inheritance. A compiler now generates reasonably fast code.

Although through VB many Win32 API calls can be made, it can be a rather tortuous process, as you need to cut and paste in every function declaration prior to usage. Some data structures and programming paradigms do not translate easily to the VB world. Tip: The reason you can't import a function such as ShellExecute() is that functions exported by the OS which take strings have an ASCII version -ending in 'A" and a UNICODE version ending in W: you need to import ShellExecuteA.

Visual Basic is a very fast way of getting an application up and running -and the built in setup kit is pretty good for distributing programs. (except that it always includes the version of CTL3D32.DLL used by your OS, and not theare separate versions required for NT and '9x). In particular it's very good at seamless OLE Automation and ActiveX integration -much better than Visual C++. This -and the fact that cut down versions come with MS Office programs means it is worth learning and using in the 'appropriate' parts of any major programming project. For example, it can be used to integrate your compiler, source code and project management tools with relative ease.

In terms of popularity, Visual Basic is probably the most widely used language on the planet, although it is not so common in commercial shrink-wrapped software products. It's good for quick and dirty development, database integration and the development of usable front ends. With the native compiler and a rudimentary object model, the language may even be usable for large or commercial performance applications.

For low level Windows hacking, it is not the tool of choice -unless backed up by DLLs, OCXs or even device drivers.

Link: review
[Top of Section] [Index]

3.3. Borland/Inprise Delphi

Delphi combines the Pascal programming language with a GUI focussed on RAD -both database and low level programs are possible in this IDE.

Like VB, it can be a fast development tool in the hands of a moderately experienced user, and there is enough of a developer community to ensure that support for new OS technologies -DirectX, IE4 Common Controls- comes out relatively rapidly. Many people love it, especially recreational programmers'. Once nice feature is that it is a reasonable language in software engineering terms.

It's worth noting that Delphi does seem to be popular for an in house development tool in many high salary financial organisations. Time to market and database integration are probable reasons for this.
[Top of Section] [Index]

3.4. Borland/Inprise C++5.x and C++ builder

A true 32 bit IDE which can still develop 16 bit and dos applications. OWL 5 provides wrappers for the common controls and windows sockets., while MFC can be used for applications where use of that framework is deemed politic.

Although apparently the system does support OCX creation and use, the lack of OCX support in the Resource Workshop, and the absence of any OCX Expert, means that it isn't really suitable for OCX development and use. It does still support VBXs in 32 bit apps though, which can be very useful for porting legacy apps.

The early 5.0 version had a reputation for leaks and bugs. Version 5.02 ships with the MFC source, so that MFC applications can also be built with the compiler.

C++ Builder is a newer Delphi-like interface to the compilation tools: it seems to be a nifty way of doing C++ coding. The Enterprise edition of this is particularly well rounded.

Links: Inprise home page
[Top of Section] [Index]

3.5. Metrowerks CodeWarrior

Mac programmers will know and love this product, which has long been the definitive development tool for "the other platform". They've recently branched out into the Windows and embedded market, and offer C++, Pascal and Java development tools for Win32 and WinCE.

With MFC support now, and a resource editor due in summer '98, and too, this could become a reasonably productive Win32 development. Low cost editions are available. One major weakness: the resource editor is very primitive compared to modern Windows IDEs.

Link: Metrowerks
Link: review
[Top of Section] [Index]

3.6. Intel VTune

This is an add on compiler and profiler for Visual Studio. It's key features are
  1. C++ and Fortran compiler that knows about Pentium III floating point registers and can generate code which makes use of them.
  2. Other compiler switches to do RISC-style aggressive optimisation techniques such as loop unrolling and conditional moves instead of branching.
  3. A very good graphical code profiler.
Because this tool is an add on purchase, it should not be viewed in the same light as the IDEs. But the compilers give it an edge over other profiling tools. As a way of speeding up code it may be exacly what you need.

Link: review
[Top of Section] [Index]

3.7. lcc-win32

This is a free win32 compiler and IDE, available in a 2 MB download, source and documentation for a $40 fee.

The IDE is not as full of 'wizards' and other clutter, and is relatively low level, but it is a good low cost introduction to Windows programming. A good install program is a nice feature, as it helps get you started easily.
[Top of Section] [Index]

3.8. Assemblers

Most of the compilers support in-line 32 bit assembly language, except Borland C++ which requires you to buy Turbo Assembler (TASM) just to get the 32 bit in-line assembler to work. Sometimes the x86 language supported in compilers is a subset of the full x86 language, with new instructions (CPUID, CMOV) omitted. Full assemblers have an edge here, such as Borland TASM and Microsoft MASM. TASM is really an add on to Borland C++, while MASM is a relic which ships with a DOS based install program but can be hosted by VC++.

There are freeware assemblers,in particular NASM . This can generate Pentium and MMX opcodes and output .obj files in Borland or Microsoft formats.

Links: Paul Hsieh's x86 Assembly page; Win32 coding in assembler
[Top of Section] [Index]

3.9. Also Available

Deserving a mention are These products exist, but do not get a regular mention, something which may reflect their lack of popularity.
[Top of Section] [Index]

3.10. Watcom C++ 11

The Watcom compilers have a reputation for generating high performance code, and also of being slightly harder to use than the MS and Borland tools. Some "real programmers" swear by them.
[Top of Section] [Index]

3.11. Microsoft Visual J++

A Java compiler which supports COM, so that Java can be used to write OLE/COM objects and call out to the OS via COM interfaces and the standard java.* packages. Many DLL exported functions can also be called from the latest (2.x) version of the compiler and VM.

Standard Java code should execute on all Java VMs, but the COM enhanced code requires a special JVM, which runs a far more limited set of devices.

For reliable code development fetch the updated compiler patches and the full Microsoft Java SDK, which contains the tools to turn a set of Java binaries into a standalone windows app. Because the MS JVC compiler is free for download it is a low cost way to start programming.

Visual J++ 6.0 is a Java 'variant' which produces code for Windows only. Given the current legal dispute the longevity of this product may be measurable in weeks rather than years: avoid it for anything other than a throwaway application.

Symantec Visual Cafe generates native Win32/x86 binaries, so could be used for developing applications, but you are restricted to the standard Java libraries (or manual imports).
[Top of Section] [Index]

3.12. Gnu for Win 32

This is project underway at Cygnus to port the gnu compiler to windows 32. It is intended to help in cross platform portability rather than windows app development, but can be used to build win32 apps.

There are four versions available, Cygnus's original Cygwin32 and Colin Peters' Mingw32 (Minimalist GNU Win32) version, each with either GCC 2.7.2 or EGCS 1.0 as the compiler. Mingw32 + EGCS is recommended as the best version for Win32 development.

The main difference between Cygwin32 and Mingw32 is that Mingw32 doesn't need the compatibility library (Cygwin32.dll and associated material) that Cygnus provides. This loses part of the Unix compatibility layer, but gives smaller and faster compiled binaries. The only reason to prefer Cygwin32 over Mingw32 would be for porting code from Unix.

Regardless of which version you intend to eventually use, you need to download the complete Cygwin32 development kit first; Mingw32 is distributed as a patch for Cygwin32. If you intend to use EGCS rather than GCC as your compiler, you only need the "user tools" version of Cygwin32, instead of the much larger "developer tools" version.

All versions come with the Win32 header files and link libraries (not quite complete and up to date, but close enough for most development requirements).

Installation can be a bit of a pain; coming as they do from the Unix world, these tools don't have the sophisticated automatic installers that Windows users expect. But if you follow the instructions and apply a bit of common sense, it's not too hard.

Relevant web sites:

  1. Colin Peters' Mingw32 project . this is the best place to start; it has pointers to everything else you need)
  2. Cygnus Solutions' GNU-Win32 project
  3. The EGCS home page
  4. Mumit Khan's port of EGCS to Win32
(thanks to Ross Smith of New Zealand for these details)
[Top of Section] [Index]

3.13. Configuration Management Tools

A source code control system is fundamental to productive, professional programming. The choice of which tool to use is a long term decision, and not to be taken lightly: most vendors have trial versions to download to enable a thorough evaluation to made prior to spending $500-$1000 a head on an inappropriate product. It doesn't take long before the system becomes a critical part of your process and the repository of all your software assets, so a mistake can cost far more than the purchase price.

Some criteria which may be used to assess a product, depending on your current and future needs are:-

Financially constrained developers can make do with the freeware gnu RCS tools, or just use the copy of Visual SourceSafe which comes with every Enterprise edition of Visual Studio.

Popular products -usually with free trial editions for downloading- include:-

Merant PVCS
A full blown CM system with optional defect tracking and web integration. Its feature set seems comparable with MKS Source Integrity. Formally marketed by Intersolv.
Visual Source Safe
This comes for free with enterprise editions of Visual Studio. It's relatively easy to start using, and integrates well with the Visual Studio product line. It's weaknesses show up over time:-
  • Branching isn't too successful as it's hard to break Studio's bindings to particular projects
  • Lacks an integrated defect tracking system.
  • The administrator can't override someone else's actions -such as undo a file checking out.
  • Doesn't scale well to very large or distributed projects.
  • Very slow on Samba servers -but good on NT. File locking is the problem, apparently.
  • Web publishing only really works to NT/Windows servers.
MKS Source Integrity
This is an expensive but well proven product. A nice feature about this one is that you can define actions to to be invoked when certain triggers occur. For example, after every check in the project leader can be emailed with a summary message, or a recompilation can be forced to verify that the code being checked in doesn’t break the build.
The GNU implementation of RCS
The ci and co commands can be used to build up an RCS database, and integrated with make and batch files with some effort. For team development you need a file system with symbolic linking, so that each team member's RCS directory points to the same place. That effectively means a Unix file server has to be used as the source repository.
Reliable Software's Code Co-op
This is an interesting shareware tool: a CM system which can use email as the synchronisation mechanism. This makes it ideal for peer-peer and distributed development.
QVCS
A shareware CM tool, which looks reasonable for individual use.
For more information, see the configuration management FAQ

NB: don’t just check it in - back it up. It's what tape drives and CD Writers are for. Most commercial products support OLE automation: with this it's an interesting exercise to write a script to get the entire heirachy into a directory tree and then tar/zip up for a vendor independent database snapshot.
[Top of Section] [Index]

3.14. What other tools are useful?

There are lots of commercial, shareware and freeware products which can improve your product's quality or development schedules.

Code analysers

Other items to consider include:- Also consider something for artwork & web page support. PhotoShop is a bit of an expensive luxury for most programmers: graphic design should really be delegated to someone with talents and skills in that area.
[Top of Section] [Index]

3.15. Books

Any manuals which come with your development tools are usually adequate in showing you round the tools themselves, but are rarely ideal for learning basic or advanced Windows programming. They are also becoming rarer and rarer, despite the feature growth of the products. Books by third parties can be significantly better -or significantly worse, if you are unlucky. The complexity of Windows applications is now such that there are also many books addressing niche areas: sockets, COM, MAPI, device IO, as well as Win32 fundamentals.

Some of the books which are highly regarded are listed below. The exact suitability of individual books depends on what you want to do and what your background knowledge is. Most of the books listed are by the Microsoft Press, as they are the publishers most interested in addressing the needs of Windows Programmers. Addison Wesley and Wrox press also have valuable and high quality titles. All of these books assume prior knowledge of C and C++. NB: DDJ maintains a good database of their book reviews, which is a good source of independent opinions on many of these titles as is this other site

One good strategy on choosing a book comes with experience: go into a bookshop and look for an explanation of something which caused you grief but you now understand -such as COM object thread safety or MFC message routing. Verify that a book which should cover this topic does so in way which you understand. If it doesn't, then you should question the book's value. Then go back to your desk and find the best value on line book store. In particular European developers will find that the cost of US editions is so much lower that they will save money on a US purchase, even once shipping costs have been included.

As well as books, there are some monthly magazines which cover Windows programming in detail:-

Microsoft Systems Journal.
A regular magazine, combining information with some evangelism for the company's latest API, tool or strategy. Often more up to date with operating systems and products than anything else.
Dr. Dobbs Journal.
Another regular magazine, good for reviews of various tools. More independent; less Windows focussed.
3.15.1 Introductory Windows Programming
3.15.2 Advanced Programming Topics
3.15.3 Low level hacking
3.15.4 Software Engineering and other topics

3.15.1. Introductory Windows Programming

These are books you can use when starting off, but may need to keep handy and even re-read in future years. A good beginners book should teach you the fundamentals of the Win32 API, including the message loop, Windows, Dialogs and Controls, drawing with GDI, and fundamental concepts of DLLs and COM. Quite a few of the entry level books tend to skimp over the full feature set of GDI, and try to cover multithreading in about ten pages. Advanced books cover multithreading in hundreds of pages, and with good reason -when things go wring it's nightmare. So steer clear of threads until you are happy with single threaded apps.
Programming Windows, Petzold (and Yao), MS Press
Charles Petzold wrote the original Windows programming 'bible' -"Programming Windows" back in the mid eighties -everyone who started Windows programming in those days had -or needed- a copy of this book. Now updated for Win32, Petzold starts the basic paradigms of windows programming -Windows and message queues- and goes on to cover many advanced topics. The book uses C and assumes a prior knowledge of this language. Although the structure of the book does not match C++ and OWL or MFC applications, the chapters on advanced topics -such as drawing- are still invaluable reference material, while the introductory chapters provide an invaluable explanation as into how Windows applications work.
Critique: Some of it is -well- dated, and not really adequately updated to the new OS platforms. The OLE section looks like an afterthought.
March 99: The latest edition is fatter, drops the OLE/COM section in exchange for a music app and adds a rudimentary Internet chapter containing a time synchronisation sample which would never work on Windows NT. There are better alternatives.
Programming Visual C++ , David Kruglinski, Shepherd and Wingo , MS Press, ISBN 1-57231-857-0
This is the successor to Kruglinski's Inside Visual C++ series. In it the authors explain how to write professional looking applications in VCC, covering areas such as the Wizards, OLE, databases, document/view models dialog boxes and basic Internet and ATL programming. For low level Win32 programming this is not the book of choice -but if you need to use MFC as the framework for your app, this is a good starting off point and a reference tome to return to.
Critique: The early editions of this book used to contain an appendix with a reasonable introduction to C++, but this is now absent. Cut and Paste is about the only code reuse strategy covered.
Win32 Programming Rector and Newcomer, Addison Wesley
An excellent alternative to Petzold. Thick and thorough, and without any reminiscing about the old days of Win16. Good value.
Programming Windows 95 with MFC, Jeff Prosise, MS Press
Covering much the same ground as Petzold, Jeff assumes you have a copy of Visual C++ and want to use the MFC classes as the framework for your applications. Knowledge of C++ or C & the Windows API is a prerequisite. This is not your average "how to use the wizards" book.
The Windows 32 API Reference
You should get an on line copy of this. The overview chapters may be worthwhile having on paper and reading, but they date so fast it's hard to justify.

[Top of Section] [Index]

3.15.2. Advanced Programming Topics

Advanced Windows, Jeffery Richter
This is the definitive guide to the new features of the Win32 API -especially on NT. Jeff covers advanced topics such as processes and threads, Overlapped IO, Completion Ports, Structured Exception Handling and UNICODE. Through a skilful use of Dialogs, he manages to demonstrate all these features without appearing to write full scale applications. Application structure and the user interface and graphical aspects of windows are not covered. [Buy this book and then write your name on it in big letters to stop it going for a walk].
A new version is due in late '99
MFC Internals, Scott Wingo
If you use MFC and want to know how it works -or why your code doesn’t behave as expected- this is a good book. It assumes you are already experienced with Win32 and MFC. One of the best adjucts to the on line documents competent MFC programmer needs. This book is not recommended as an introduction to MFC programming.
Inside Windows NT, Second Edition, David Solomon, ISBN 1-57231-677-2
The original edition by Helen Custer was mindnumbingly dull, but after a near complete rewrite the book can now be read from cover to cover. Not only that, it is full of valuable snippets of information and little experiments you can run on your own NT box to peek behind the scenes.
Worthwhile if you're getting into device drivers or want to know what the OS is really up to. Applications should not have to know all this nitty gritty, but the section on scheduling is useful are other chapters on subjects such as file I/O and memory management.
Critique: it lives in an ideal world, in which Blue Screens never happen, NTFS corruption never occurs and NT's security model is both comprehensible and comprehensive.
Programmer's Guide to Windows 95, ISBN 1-55615-834-3
Covers all the new Win95 features and differences with NT. Fairly readable. Part of the MSDN/Win32 on line documentation, so not worth shelling out for on paper. Clearly due for an upgrade.
Inside COM, Dale Rogerson
A book which covers the fundamentals of the component interface model without covering the specifics of the OLE linking and embedding interfaces. Vaguely useful for anyone using COM within or between applications. NB: sequels to this book -Inside COM+ and Inside Distributed COM are in the pipeline.
Inside OLE, Kraig Brockschmidt,
This was the original OLE and COM book -and was never an easy read, even if the second edition is much better than the first. Nowadays it has less appeal: other books cover COM better, so this one is only of interest to people with the unwelcome task of implementing OLE2 in raw C/C++. Flicking though this book, you will realise why this is best left to suppliers of libraries such as MFC, OWL and ATL.
Essential COM, Don Box, ISBN 0-201-63446-5
This is a good book -good enough to supplant Inside COM as the definitive bible for COM development. Don's experience broad experience in COM and CORBA, and critical insights into COMs failings give the book more value than MS press offerings. Also it's reasonably up to date, and covers NT5 to an extent. Some chapters are on MSDN. As is common with all COM books, you may get a headache reading it.
Professional ATL and COM, Richard Grimes, Wrox Press
This book fills a niche: how to really make use of ATL, and is a practical counterpart to Don's book. It seems overpriced, the ATL3.0 version costing 50% more than the ATL2.0 book. But if ATL is your chosen class library, $60 is a trivial investment, and if you look round the online booksellers you can get down to a more reasonable price. And it is reasonably readable, full of practical examples and relatively error free.
Win32 System Programming, Johnson M. Hart, ISBN 0-201-63465-1
This is quite a good follow on book to Richter's, focusing on low level synchronisation and communication with a definate Unix like flavour. J.M. Hart is pretty rigorous when it comes to thread safety, so this book may come in handy if you are writing low level or server applications.
Visual Basic, Bruce McKinney ,ISBN 1-57231-422-2
If you really must insist on doing Win32 coding in VB, then read this book -it's on the MSDN CD, albeit without the sample apps. It's actually stricter on coding practices than many of the C++ books, which is as good a reason as any for VB programmers to read this book. And in a world with ubiquitous VBA, all windows Programmers benefit from acquiring VB skills. This book will let you write moderately serious Win32 apps without having to take on the MFC Wizard.

[Top of Section] [Index]

3.15.3. Low level hacking

Inner Loops, Ralph Brown, ISBN 0-201-47960-5
An introduction to x86 assembler for anyone interested in tuning the core of their apps. It's probably due for an upgrade in the 'Katmai timeframe', as it doesn't cover all the subtleties of programming for the latest generations of Intel processors or AMD/Cyrix cores.
Windows Assembly Language and Systems Programming, Barry Kauler, ISBN-0-87930-474-X
Apparently the only book on Windows programming in assembler there is.
Computer Architecture: A Quantitive Approach, Patterson and Hennessy, ISBN 1-55860-329-8
This isn't really an x86 or Windows programming book, but its sections on Pipelining and Instruction Level Parallelism provide the underpinnings of how P6 generation cores work. The memory-hierarchy chapter explains everything you need to know about uniprocessor caches, while the multiprocessing section is the definitive reference of 'relaxed consistency models' for multiprocessing. These are where different CPUs get to see memory writes in different orders: exactly the behaviour you see on a multiway P6/PII box. After reading this book and inner loops you may be able to write code to extract maximum performance from these systems -although for ease of maintenance you may well conclude that is not the route you wish to follow.
Intel Processor Documentation, Intel
PDF files you can download from Intel's developer web site. Get the Intel Architecture Optimisation Manual at the very least.
Developing Windows NT Device Drivers Dekker and Newcomer, Addison Wesley, ISBN 0-201-69590-1
A gentle introduction to device drivers which is as up to date as you can hope (Win98 and NT5 beta 1) with NT and WDM drivers. Readable and with an appendix of common kernel mode API calls. A valuable counterpart to the OSR book, especially if you are just starting out. The list of hardware tasks to run away from is particularly amusing, perhaps even poignant.
Windows NT Device Drivers Mason and Viscarola, OSR
This is the new bible of Device Driver hacking -best value when bought direct from OSR. After reading it you still will be a long way off from writing production quality device drivers, but at least you will have a vague idea of the effort involved. A lot less of an entertaining read than Dekker and Newcomer

[Top of Section] [Index]

3.15.4. Software Engineering and other topics

Many books teach Windows application programming -but the whole engineering process gets neglected somewhat. If you are interested in delivering quality Windows applications to meet schedules -or are working in a team, then software engineering skills are as important to develop as programming skills. To an extent, they are even more important, especially if you have long term career plans.

Recommended reading here includes:-

Code Complete, Steve McConnell, MS press
This is a great book on learning how to write high quality code -and how to debug the bits that aren't so good. It predates C++, COM and interfaces, so some of it's strictures have to be taken with a pinch of salt. However, it is still one of the best books to get 'programmers' on the path to becoming 'software engineers'. Mandatory Reading for software professionals.
Rapid Development, Steve McConnell, MS press
This covers many of the process and organisational issues of team software development. If you are developing by yourself, for yourself, then you can skip this book. Otherwise, it's great. The 'classic mistakes' page is worth photocopying and pinning up on your wall -and the 'what to do when things go wrong' chapter is an excellent rarity in methodology books which always assume that processes are followed and disasters never happen.
Design Patterns, Gamma et al
This is a good book during application design, although in the MFC world half the design is given to you, whether you want it or not.
About Face, Alan Cooper
This book deserves a mention as a classic book on UI design which anyone who designs applications ought to own. It's getting a bit dated these days, as it predates a ubiquitous web.
The Art of Software Testing, Glenn Myers.
There are seemingly no books which cover testing of Windows applications. Instead you have to resort to books such as this 1979 volume, which covers the basics of testing software. It hasn't dated much, although you can help laughing when it describes a thousand line program as 'large'. NB: if testing is important, download our Win32 app walkthrough checklist

[Top of Section] [Index]

4. Win32 Platforms

This section covers the various platforms which support Win32, and the differences between them.
4.1 What Win32 Platforms are there?
4.2 What's in Windows 95?
4.3 What's in Windows NT?
4.4 What about Win32s?
4.5 And WinCE?
4.6 What's in Windows 98?
4.7 What's coming in Windows 2000 Professional?
4.8 Do I need to worry about Win64?

4.1. What Win32 Platforms are there?

Although Win32 is a single programming "interface", there are multiple implementations of this interface, each with their own strengths and weaknesses.

The most widespread platform is Windows95, although Win98 will eventually replace this. Because these two OS versions are often similar, "Win9x" and "Windows 9x" is often used to refer to both of them. The Win9x implementation of Win32 is the most common one found in households and laptops. Because it has evolved from DOS and Win31, its legacy application and hardware support the best, but the overall performance and functionality is hampered by the all the legacy code it both contains and supports.

Windows NT is the heavyweight implementation of Win32, offering much more functionality. Because of its heavy system requirements (realistically a P5/133 and 32+MB RAM), it is normally only used in office desktop and server environments, although corporate laptop use of NT4 is quite high despite its lack of mobile user support.

A well written application can usually run on Windows 9x and NT, possibly changing its functionality at run time. Tip: GetVersionEx is the API call to distinguish between platforms and versions.

Windows CE is the latest addition to the Windows Family. It contains a very cut down kernel and is intended for consumer products and embedded systems. Although an experienced Windows programmer can be programming for CE within a matter of days, the hardware for CE platforms is so radically different from that of classic PCs that designing a single application to run across Win9x, NT and CE is not currently a common practice.

It has long been Microsoft's stated objective to replace the Windows9x kernel with NT. This will be a slow process, as it will not happen until the majority of PCs in regular use are up to running a consumer variant of NT, and all applications and hardware support the OS. Application and hardware developers need to bear this long term strategy in mind, and design for both desktop operating systems.

The future of WinCE is unclear. Its current rate of evolution is immense, and is appearing in some interesting products -especially the Sega games console. It has the potential to become the most widespread Windows platform of all: used almost everywhere a 32 bit embedded CPU is found. It may also fail to justify the current levels of investment, and become another "whatever happened to…?" story in the computing press.

Also deserving a mention is "Win32s", a subset of the Win32 API which can be supported on Windows 3.1 if the appropriate drivers are installed. Use of Win32s is not advised by Microsoft, and recent products (Visual C++ since version 4.2, VB5) can not be used to generate Win32s executables. It was originally intended to serve as a transitional API between Win31 and Nt/Win95, and it is generally now felt that people should really have upgraded to one of these operating systems by now. In the corporate world, support for Win31 may still be a requirement, in which case Win32s is one way of doing so. The platform has also been making a comeback with web browsers for Windows 3.1.
[Top of Section] [Index]

4.2. What's in Windows 95?

Win95 has lot of "gotchas", as not all of the full Win32 API could be implemented. Reasons for the restricted functionality are probably a combination of time, effort and compatibility needs. The missing features are mostly documented in the "platform differences" section associated with each API call entry in the manuals.
[Top of Section] [Index]

4.3. What's in Windows NT?

NT tends to lag on some of the home oriented APIs-such as DirectX, although this may change in future. Some of the major details for programmers are:-
[Top of Section] [Index]

4.4. What about Win32s?

Win32s is "Win32 for Win31", and is a half way house between 16 bit windows and the 32 bit world. A better Win31 application can usually be written with 16 bit tools. Using Win32s enables you to use slightly more modern tools, but there is still bound to be enough differences between full Win32 and Win32s executables that a separate code base is often required. This code base separation can usually be restricted to a few #defines and platform specific modules.

The most up to date version of Win32s is version 1.3: this came out with Win95 and supports the common controls such as tree and list views. Future development is unlikely, as MS do not want anyone to run Win31 any more.

Versions of Visual C++ after -and including- 4.2 do not support Win32s; version 4.1 is the most modern one to do so. The apps you build with VCC4.1 must link dynamically (not statically) to the RTL and class libraries. Look under win32s\redist and win32s\debug on the CD for these DLLs.
[Top of Section] [Index]

4.5. And WinCE?

Windows CE has a very cut down API, with a completely different kernel, an Object Store as well as a file system and lots of support for networking from the devices. The API is documented on MSDN Library, the emulation SDK shipped in the Professional subscription and the full cross compiler with a universal subscription.

Some features of the current (CE 2.x) versions of the OS are:-

Expect a new release of the OS annually -at least until the end of the century. [Top of Section] [Index]

4.6. What's in Windows 98?

  • Internet Explorer 4.x becomes integral to the OS, bringing many Internet related services to all systems. [Win98SE comes with IE5 instead].
  • Waitable Timers and new power management API calls. -like SetSystemPowerState()
  • DirectX 5.1 with AGP support and DrawPrimitive for 3D gaming.
  • A new driver API "WDM" for writing drivers for devices on new buses such as USB and FireWire (1394)
  • A new video streaming architecture with an emphasis on IEE1394 and USB bus devices
  • FAT32 upgrades for large hard disks
  • Multiple Monitor support
  • Visual Basic Scripting & an OLE automated shell
  • Built in features now include the task scheduler, font smoothing and deep (256/64K) colour icons.
  • The Microsoft implementation of the Java VM and associated class libraries (most of Java 1.1, plus AFC)
  • Many new UI controls: the "CoolBar", Bands, a date/time picker, an IP address control.
The most visible change for programmers is the IE4 shell: a web browser will be built in, the new common controls can be used and applications can be made to look better -or at least different. This also forces programmers to upgrade their Win95 applications to avoid looking too dated.

Win98 retail includes IE4, and a Java compatible virtual machine which includes most of the Java1.1 APIs. Windows 98 Second edition adds IE5, DirectX 6.1 and other new features as well as various bug changes.

Link: review for programmers
Link: Win98 SE update
[Top of Section] [Index]

4.7. What's coming in Windows 2000 Professional?

In the OS formerly known as NT5, we can probably expect:-
  • Almost verything in Windows 98 SE
  • Lots of server-side stuff: Active Directory, multiple mount points in the file system
  • Com+ : an upgraded version of COM/DCOM. COM+ Events are kind of neat.
  • Asynchronous RPC/COM -good over slow links.
  • Native Structured Storage. This will boost the access speed of OLE files.
  • New GDI services: Alpha Blending and gradient shading.
  • The long promised "Cairo" Object File System extensions to NTFS.
  • RegisterSysMsgHandler() to let console applications catch messages.
  • Security enhancements such as smart card support and file system encryption.
  • Toolhelp32 is finally supported.
The most up to date information will come via MSDN, and from Microsoft Systems Journal.

Hints are already arriving as to the features of later operating systems. GDI 2K may be the drawing interface for this -it sounds like a COM based successor to classic GDI. DirectDraw is probably the most realistic forerunner of this API. A consumer version of Win2K will use the NT kernel, probably with all the enterprise baggage stripped out. Given the historical difference between promised and actual ship dates of MS OS products, don't hold your breath for these new toys.
[Top of Section] [Index]

4.8. Do I need to worry about Win64?

Not for a while, no. Although the Win32 API for NT5 is being made compatible with a 64 bit version of Windows, it looks like it won't be late 2000 before a Win64(TM) OS ships. Expect to see it first on Merced servers with high end workstations following. Win32 systems will still sell in their millions for years afterwards, as Merced implementations are too power hungry for laptops and too expensive for home systems. And no doubt the Win64 boxes include support for everyone's Win32 apps

Unless you make or sell server side products that need 3+ GB of real or virtual memory an early migration to Win64 could be a dangerous diversion. If you sell end user applications for the home and office market, then you may not have to worry for years. After all, Merced will run x86 apps at a decent rate -so they say.

But server apps and high end workstation apps could benefit from a Win64 port, so developers in these segments should start getting Win64 ready. Everyone else: avoid putting in fatal flaws in your Win32 code, so as to make the migration to Win64 that much easier when the time comes. Beware of starting too early however and wasting development time on what may turn out to be the wrong direction -the mistake Lotus and Wordperfect made when porting their DOS apps to OS/2 instead of Windows 2.x

Microsoft are starting to evangelise Win64, and no doubt Intel will too as Merced's ship date draws nearer. Intel want to ensure the success of Merced. Microsoft want NT to enter the Mainframe world, and view Merced as the key. Intel are vulnerable to MS NT5.x timescales slipping, or simply to their inability to produce a decent compiler. To get maximum performance from an 'EPIC' architecture you need a compiler which not only unrolls loops, but interleaves different loop iterations for parallel execution. Given that Visual C++ for x86 still hasn't discovered loop unrolling or the P6/PII conditional move opcodes, they have some way to go. This may explain Intel's recent backing of Linux.

For professional developers (or their employers), the main priority is usually obtain maximum revenue for the minimum amount of work. Each platform to support is another compilation and QA process, with the extra complexity of even more complex support calls. In other words, cost. Minimising (or eliminating) source code variations between platforms is critical.

Things to do now

  1. Note that Win64 Pointers are eight bytes long, not 4. So casting between DWORD and VOID* is no longer acceptable.
  2. There are extra typedefs for ints and longs that are pointer sized and can be used for arithmetic.
  3. Data structures need to be aligned in memory for maximum performance. DWORD on 4 byte boundaries, QWORDS/int64 on 8 byte boundaries. The compiler will do this automatically -but packed structures can burn you.
  4. Don't include any x86 assembler or machine code -or keep it in a module with replacement implementations in your language of choice.
  5. Stop trying to write dual mode win16/win32 code. You probably won't regret it.
  6. Be careful of #ifdef WIN32 sections intended to hide features from a 16 bit build catching you out on a WIN64 build.
  7. The size of LRESULT, WPARAM and LPARAM will all expand to 64 bits, so message handlers will have to be checked for inappopriate casts. Presumably a new version of windowsx.h will help crack any changed messages.
  8. Design persistent data structures (files, down the wire formats) to scale gracefully to 64 bits. Using __int64 for the persistent form is easy enough to do today. LONGLONG works in IDL files, but VB doesn’t yet know what do do with it.
  9. Make your source UNICODE ready today, even if you don't ship a Unicode build. The earlier you use TCHAR and the portable functions, the less work you'll have in the future.

WinCE developers may already have noticed that some of the MIPS processors used by some OEMS (NEC, for example) are based on the R4000 design, which already uses 64 bit registers. So it may be that a 64 bit version of WinCE is waiting in the wings.

There is of course "another way". If you write Java apps you offload the final translation from bytecodes to native CPU until the last moment -giving you an instant rebuild to Alpha, Merced, Power PC, whatever. And with both key players in the Merced project (HP & Intel) Java licensees, hopefully they will be busy funding work on aggressive JIT compilers for the platform. Now portable Java apps may not offer all the OS support you need, but MS JVM apps -or even better COM objects- may well migrrrrate from Windows platform to Windows platform seamlessly.
[Top of Section] [Index]

5. Programming Questions

This section covers many common programming questions. Because the possible ways in which a windows program does not work is probably provably infinite, only a small subset of the possible questions are covered here. Other useful Internet Resources are listed near the end of the FAQ.
5.1 Application Design
5.2 Sound and Graphics
5.3 Low Level, Device and Real Time stuff
5.4 Shell and User Interface

5.1. Application Design

Fundamental application design problems
5.1.1 How do I port my 16 bit app to 32 bits?
5.1.2 Common Pitfalls in porting from 16 to 32 bits
5.1.3 How can two programs communicate with each other?
5.1.4 How can two programs communicate across a network?
5.1.5 How can I tell what version of windows I'm running?
5.1.6 How do I write a screen saver?
5.1.7 What is a Callback function?
5.1.8 How can my 32 bit program call a 16 bit library?
5.1.9 How do I translate the value returned by GetLastError() into a string?
5.1.10 Why are all my Exe files so big?
5.1.11 How many threads can a program have?
5.1.12 How do I get my program to start even if a user is not logged on?
5.1.13 What is the file format of .{exe, ico, bmp, ttf, wav, avi,doc,xls, ...etc} files?
5.1.14 How do I patch API entry points?
5.1.15 How do I add power awareness to my app?

5.1.1. How do I port my 16 bit app to 32 bits?

The good news: it's easier to go from 16 bit to 32 bits than vice versa. The bad news: it can still be hard work.
  1. Get the 32 bit version of your development tools
  2. Get the 32 bit versions of any support DLLS/VBXs
  3. Read the "Creating Great Applications for Windows 95" and "windows 9x logo requirements" articles and understand the implications.

Trying to compile your program with a 32 bit compiler is usually the first big step: fix all the errors it shows and then see if it works when it is run. A raw API app can just be rebuilt, using PORTTOOL.EXE to help you. Using the "windowsx.h" macros and message crackers can assist you here. Class libraries often provide the message cracking for you, so make life a bit easier. MFC Apps can be ported fairly quickly by opening up the project in Visual C++ and rebuilding. For OWL apps, just create a new 32 bit target or a new project with a 32 bit exe as the destination.

You may be disappointed to find little or no performance improvement, or even worse a slowdown. The latter is most likely on Windows 95, where a lot of the OS is still 16 bits wide. The real speedup of win32 comes with higher power processors, and Windows NT. The new features of Win32 will still benefit application son Win95, and with some extra programming (threads & async IO) performance can be significantly improved.
[Top of Section] [Index]

5.1.2. Common Pitfalls in porting from 16 to 32 bits

  • Integers are bigger. This can break IPC and reading old files.
    Fix: For legacy structures redefine int references to short
  • Structure alignment has changed. Causes the same problems as above.
    Fix: return packing to BYTE alignment for these structures. The include files "pushpack1.h" and "poppack.h" can be used around these structure to fix them.
  • 0xffff is no longer equivalent to (UINT)-1. Use the macros in "limits.h"
  • No DIB.DRV. Use CreateDIBSection() to create a DIB which you can apply GDI calls to, and use BitBlt() to draw it afterwards.
  • A changed comms API. Some thing like DCBs remain, but comms ports are just another type of file now, with blocking I/O being the easiest way to wait for input.
  • Long file names. Make sure that MAX_PATH is used to declare all string that can hold a path, and do not assume that file names have an 8.3 format.
  • The implementation of Unicode or ANSI in the Win32 API is assisted by lots of macros to bind to different actual functions. For example TextOut is a macro mapping to TextOutA()or TextOutW(). This can cause problems in C++ when you have a member function whose name matches a windows API function as the macro renames it.
  • No VBX support. Actually Borland 4.5 manages this with a mixture of thunking (Win32s, win95) and inter-app message redirection (NT3.5 onwards) .
    Fix: Use OCXs instead. C++ users will need BC5.0 or VCC4.0 to use these.
  • Passing handles to GDI & memory objects between applications in PostMessage calls is harder. System objects must be duplicated using DuplicateHandle(). Memory can only be exchanged via shared memory or WM_COPYDATA messages.
  • Calling DOS and other interrupts direct. You will probably find an API substitute somewhere in all the documentation, but BIOS calls are pretty much off-limits.

[Top of Section] [Index]

5.1.3. How can two programs communicate with each other?

In Win16 this used to be done by posting/sending messages containing pointers to data structures in the single shared memory space. With each Win32 process this no lnger works -although it is great for inter-thread communication
  • SendMessage() and PostMessage()
    Only works for the data which can be fitted in to the two 32 bit parameters WPARAM and LPARAM, unless you can pass a pointer to shared memory.
  • WM_COPYDATA.
    Easy, good for small quantities of data. Works between 16 & 32 bit programs. NB: you need to manually add it to your 16 bit header files.
  • OLE Automation.
    Fairly easy but restricts you to automation data types and is not as fast as other methods.
  • COM
    Fast but requires interface declarations and the MIDL compiler. The ATL wizard simplifies this
  • Memory mapped files
    Only for 32:32 IPC. Needs some synchronisation mechanism/objects
  • Named Pipes
    Distributable, but you can't create the server side on win9x. This limits their value somewhat
  • Sockets
    Communication to a local host via winsock is certainly feasible, and good for writing apps which can be distributed. You do need to verify that such apps running on modem based PCs do not keep on trying to dial to their ISP when connections are made.

[Top of Section] [Index]

5.1.4. How can two programs communicate across a network?

There are lots of ways to do this: the most popular are probably sockets and DCOM.
  • Winsock
    Powerful & cross platform, but often a bit low level. Winsock 2 provides more protocol independence so socket apps can run over IPX, IP and other protocols, but is a bit fiddlier to use. Used as the foundation for pretty much everything else, especially when you are trying to implement an Internet protcol from scratch. NB: Beware of byte ordering and structure packing issues when talking to non-Win32 platforms.
  • Distributed COM
    This is built into NT4 and win98, and available as an update for Win95 -and with all IE4 upgrades. DCOM has a lot of security support, which can be geod or bad, depending on the task. With DCOM1.3 you can even use HTTP as a transport, which lets you talk DCOM through a firewall via a proxy server.
  • Inet.dll
    This library comes with IE3 and later and gives you rapid client access to web and ftp servers. Implement your server as a web server extension (IIS, Perl, ASP, JSP, whatever) and you are away.
  • DCE/Microsoft RPC
    You need the win32 SDK to use this. But you may be able to talk to Unix boxes.
  • Named Pipes
    Note that you can't create the server side on win9x, which limits their value as a peer-peer tool.
  • Mailslots
    When broadcasting a message to all clients in a workgroup, the message is sent over every transport: clients may therefore receive multiple copies. Design your protocol to handle this.
  • Email
    You can use an email system such as Exchange or SMTP as the transport.

[Top of Section] [Index]

5.1.5. How can I tell what version of windows I'm running?

With the function GetVersionEx(). This fills in a structure indicating whether or not the OS is NT, and what the version number of the OS is
BOOL  InWinNT() //test for NT nature
{
	OSVERSIONINFO osv;
	osv.dwOSVersionInfoSize=sizeof(osv);
	GetVersionEx(&osv);
	return osv.dwPlatformId==VER_PLATFORM_WIN32_NT;
}
The major and minor elements of the structure help to differentiate beween versions more usefully than build number. NT4 is (NT, 4, 0), NT5 is (NT, 5, 0). Win95 is (no NT, 4, 0) while '98 is (no NT, 4, 0x10), build 1998. Win98 SE is build 2222 or later.
[Top of Section] [Index]

5.1.6. How do I write a screen saver?

You look in the on line help: "Screen Savers", or in the example code which your compiler ships with for a sample saver. The main points to know are
  1. a saver is just an executable (.EXE) with a .SCR extension
  2. the setup dialog is invoked with a /c argument; otherwise the app just shows the saver.
  3. when invoked with "/p hwnd" then it's preview mode
  4. On Win98 the savers need to handle mouse and keyboard presses and password checks themselves: on NT this is all done for you by the OS, which closes the window when it is appropriate.

There are some more details elsewhere on this site, but the best documentation and example code is at Lucien's Screensaver Site.
[Top of Section] [Index]

5.1.7. What is a Callback function?

These are quite common in Windows, and can be an intimidating concept. Put simply, a callback function is a function in your program, the address of which you pass to the OS or some other DLL. This external code 'calls back' your function when it feels like it.

Callback functions are central to Windows: every window has a callback function -the Window Procedure- associated with it, which is called whenever the OS wants to send a message to the window. Other places that callback functions crop up is in hook procedures, callbacks invoked when a hooked system event occurs, and in enumerations -such as when you call EnumWindows().

A key feature of callback functions is that the rules for passing parameters and the number and type of parameters passed must exactly match what the OS expects, or Bad Things happen. Usually the compiler warns you when you try and break the rules -most often when you try and use a C++ member function as a callback. The hidden 'this' pointer prevents non-static member functions from being used in this way.
[Top of Section] [Index]

5.1.8. How can my 32 bit program call a 16 bit library?

NT: You can't do this directly. You will have to write a 16 bit stub app which forwards commands and responses via some IPC mechanism such as COM.

Win9x: Use flat thunks. The thunk compiler is in the SDK, and the documentation is in the Programmer's guide to win95.

Win32s: Generic Thunks
[Top of Section] [Index]

5.1.9. How do I translate the value returned by GetLastError() into a string?

With FormatMessage(), asking for the system message tables. This is a good i18n technique, as the OS can return translated strings itself. NB: does not work in CE, as the error strings aren't included in the ROM images.
BOOL GetFormattedError(LPTSTR dest,int size)
{
	DWORD dwLastError=GetLastError();
	if(!dwLastError)
		return 0;
	BYTE width=0;
	DWORD flags;
	flags  = FORMAT_MESSAGE_MAX_WIDTH_MASK &width;
	flags |= FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS;
	return 0 != FormatMessage(flags,
			NULL,
			dwLastError,
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
			dest,
			size,
			NULL);
}

[Top of Section] [Index]

5.1.10. Why are all my Exe files so big?

Either you have all the debug and browse info included in it, or you have statically linked to MFC/OWL instead of using the DLL versions.
[Top of Section] [Index]

5.1.11. How many threads can a program have?

Every thread created takes up some space in the system. At least 12KB of unpageable memory is used kernel side for a stack, plus whatever is created user side on a per thread basis by the application and associated DLLs. Any DLL which uses thread local storage will add per-thread overhead.

The OS reserves -but does not commit- the thread's user side stack in virtual memory. Thus 128 KB or more of the 2 GB VM space is taken up for each thread.

There is no CPU overhead of having large numbers of threads waiting to run -the scheduler uses a doubly linked list oooor to schedule threads in each priority queue.

That seems to hint that you can have as many as you want, within the bounds of available memory on the target system. However, to get productive work done, keeping the number of threads ready to run close to the number of processors is the most efficient thread design. One thread per processor on an otherwise idle system should give peak performance. If you have a design that uses 2000 threads -one per client connection or whatever, thhhhen you have come up with an application design that may be elegant but it doesn’t scale well. The "thread pool" architecture -as supported in IO Completion ports and implemented in most web, file and database servers is a better design.

NT4 (service patch 3) and NT5 support "fibers" which are threads scheduled by the applications themselves. These are possibly lighter weight than standard threads, but seem so rarely used that the limits have never been explored.
[Top of Section] [Index]

5.1.12. How do I get my program to start even if a user is not logged on?

NT: Make it a service.
Win9x: add it to the list of registered apps under HKCU\Software\Windows\CurrentVersion\RunServices. This only runs when someone is logged in, and gets reloaded whenever one user logs out and another user logs in -use a Mutex to catch re-entrancy.
[Top of Section] [Index]

5.1.13. What is the file format of .{exe, ico, bmp, ttf, wav, avi,doc,xls, ...etc} files?

Common file formats are documented on the MSDN disks. The 'Office' formats come with a very strict license agreement, specifically that you are only going to use these formats for Windows platforms and then not to write your own spreadsheet and word processor. TrueType fonts are documented somewhere on Microsoft's ftp site and are more complicated than you'd think.

The definative on line site for file formats is Wotsit
[Top of Section] [Index]

5.1.14. How do I patch API entry points?

Unlike the Win16 world, you are not allowed to patch the API calls for all applications by editing USER, KERNEL and GDI. However, patching the API calls a single app makes is easier in Win32 than Win16: you just modify the jump table at then end of the application. To modify all applications' entry points you need to apply the same technique but also inject your DLL into each ones' address space.

Consult [MSJ Dec 1994 v9#12], and Richter's Advanced Windows for details.
[Top of Section] [Index]

5.1.15. How do I add power awareness to my app?

Now that the Windows logos require apps to be power aware, a lot more people have to worry about implementing what was previously as much a curiosity as non rectangular windows. Actually implementing it isn't that hard -it's testing it that really hurts.

This topic is covered in detail in the Team Iseran Programming Articles
[Top of Section] [Index]

5.2. Sound and Graphics

5.2.1 How do I load/display a 256 color bitmap using LoadBitmap (or CBitmap)?
5.2.2 How do I get the screen into a bitmap?
5.2.3 How do I draw a pixel in a faster than with SetPixel?
5.2.4 How do I get a handle to the desktop window?
5.2.5 How do I play a sound?
5.2.6 How do I play multiple sounds simultaneously?

5.2.1. How do I load/display a 256 color bitmap using LoadBitmap (or CBitmap)?

You can't, it throws away the palette. Use {Find, Lock, Load}Resource() to load a device independent bitmap (DIB) instead. The function LoadImage() can also load deep color images, and do other tricks such as load it into a high performance 'DIB Section'

You will also have to learn about palettes and their management. "Animation in Win32" has some good explanations of this.
[Top of Section] [Index]

5.2.2. How do I get the screen into a bitmap?

If all you want is a static snapshot of the screen, ALT-printscreen works quite well, and HTML help workship includes tools to snap wndows quite nicely. If it is a run time screen grab you are looking after, then a call to GetDC(NULL) returns a device context covering the whole display. Writing into this is considered rude, but copying from it into a bitmap is easy.
[Top of Section] [Index]

5.2.3. How do I draw a pixel in a faster than with SetPixel?

Well, there is SetPixelV -a marginally faster implementation. It still involves a lot of overhead and is unworkably slow for filling in a whole bitmap.

The standard technique is to use a device independent bitmap (DIB), where the bitmap's data is actually stored in the app's own memory. Standard memory reads and writes are all that is needed to manipulate the image. To get the image on screen, call SetDIBitsToDevice. Note that DIBs are usually upside down, and each scan line must be aligned to end on a 4 byte boundary. You can use the CreateDibSection function to do something profound: return a region of memory which can be addressed like a dib, and a HBITMAP handle with which the same region can be drawn using the standard bitmap function calls. This gives you faster blitting of the pixels to the display, and lets you use GDI commands to draw into the bitmap.

Finally, the absolute fastest drawing mechanism is DirectDraw, which lets you draw directly into the frame buffer.
[Top of Section] [Index]

5.2.4. How do I get a handle to the desktop window?

The function GetDeskTopWindow() used to return the window on the desktop, and it still returns the base window of which all others are effectively children. Since Win95, the desktop that you see is actually provided by the explorer, usually a couple of windows under one called "Program Manager".

IE4 and successors go one step further, with the ActiveDesktop. Again, you can rummage around with spy to find out the names and classes of windows which your own program will have to find and manipulate itself -but you run a major risk of things breaking unless you are very careful.
[Top of Section] [Index]

5.2.5. How do I play a sound?

With PlaySound(), MessageBeep() or the low level waveOut() calls. You will probably need to link in the multimedia libraries too. (add WINMM.LIB to your project). The games sound API, DirectSound, permits advanced techniques: mixing, 3D positioning of sources and provides low latency access to the sound buffers.
[Top of Section] [Index]

5.2.6. How do I play multiple sounds simultaneously?

You have to use the DirectSound API to do this; it provides a means to mix multiple sound streams into a single output stream.
[Top of Section] [Index]

5.3. Low Level, Device and Real Time stuff

5.3.1 How do I access hardware via IO ports or mapped memory?
5.3.2 How do I handle interrupts in my Win 32 program?
5.3.3 How do I read/write the serial port?
5.3.4 How do I read/write the parallel port?
5.3.5 How can I get a thread to respond in under 10 milliseconds?
5.3.6 Can I use Win9x, NT or CE as a real time OS?
5.3.7 How do I do system wide keyboard and mouse hooks?
5.3.8 How do I measure time in my program?

5.3.1. How do I access hardware via IO ports or mapped memory?

You can get away with port IO in user level code on Windows 95 & 98 through assembly language instructions like "__asm in al,dx" and "_asm out dx,al" . The VC5 header file <conio.h> defines _outp() and _inp() functions which you can use -even if you aren't supposed to. However, some ports may not respond as expected, because device drivers can talk to them simultaneously. Life is easier (and more portable) if you can use device drivers -and for standard COM port and parallel port programming this is usually the case.

For any port IO in NT, or serious device access in win9x, you'll need a device driver. Have a look at the device driver FAQ , or some of the driver programming groups -none of which have the word driver in their title to improve the signal to noise ratio. (key words: VxD and kernel mode) The NT DDK samples you need to look at are DDK\SRC\GENERAL\{MAPMEM, PORTIO}

Doctor Dobbs Journal in May 96 had an article called DirectIO which showed how to add a device driver to tweak the NT task protection masks so that in and out instructions are allowed in user mode code. This is an invaluable trick for non-commercial & prototype applications, but not acceptable for shipping products. NT separates device drivers from user code for valid reasons: performance, reliability on multi-processor systems and to enable applications to be more portable.

There are a pair of low cost shareware device drivers which claim to support device IO and interrupts from user mode code. The commercial product WinRT from Blue Water Systems can do this and more.

Link: Interfacing hardware to the PC
[Top of Section] [Index]

5.3.2. How do I handle interrupts in my Win 32 program?

You can't. You have to write a device driver or VxD, or buy a tool which catches the IRQ and forwards it to your application.

Writing device drivers is not as hard as it sounds -especially WDM drivers. It just needs extra learning and a more complex debugging setup. Otherwise, follow up some of the URLs in the previous section to see if their products meet your needs.

NB: Some device drivers (such as the standard serial port driver) can set Event objects in response to external state changes (i.e. some of the RS232 lines). These can be used by normal applications. The response time is under 20 milliseconds on NT workstation, months (well, 55+ milliseconds) on Win9x.
[Top of Section] [Index]

5.3.3. How do I read/write the serial port?

Win16 used to have lots of special functions such as ReadComm() and WriteComm() to do this, but in Win32 you just open a serial port like any other file:-
                 //open COM1 for read and write
hPort=CreateFile( "COM1",
                  GENERIC_READ | GENERIC_WRITE, //bidirectional
                  0, 
                 NULL, //no security
                 OPEN_EXISTING,  //this must be set; the ports are already created
                 FILE_ATTRIBUTE_NORMAL, // maybe with | FILE_FLAG_OVERLAPPED  
                 NULL );
Standard ReadFile() and WriteFile() functions can then be used to read or write to the port. To set the port up reliably, COM port specific functions need to be used, so look up the online help for details on the following f