|
Firepower's repost of Steve Loughran's WinAPI
FAQ Original
Source (if still available) |
|
Right after ... Books for 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.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? |
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]
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:
- KERNEL
All the low level kernel services
- GDI
Graphics Device Interface: drawing and printing
- USER
User Interface controls, windows and messaging services
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]
- Integers are 32 bits wide: sizeof(int)==sizeof(long)==4
The 32 bit
registers of the CPU (eax and siblings in the '386 and up) are used to
manipulate these numbers, giving better performance.
- Different parameter packing on some windows messages (especially
WM_COMMAND)
- lots of new API calls.
Kernel: threads, lots of memory and
asynchronous I/O stuff. Lots of new file handling routines, plus security
built in.
GDI: 32 bit co-ordinates, plus Co-ordinate Transform Matrices
and paths (in NT)
User: the Chicago common controls and shell extensions
- Console mode apps can use all the API, and even create windows.
Window-based apps can create consoles too -great for debugging.
- Structured Exception handling can make your programs more robust, or at
least allow them to tidy up after a crash.
- The header files are a lot larger and better structured.
[Top of
Section] [Index]
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:-
- To get the much coveted Designed for Windows logo
- To improve programmer productivity through state of the art development
tools and a better API
- To take advantage of the new APIs and more stable execution environment
- To work with long file names. [NB: some workarounds here for MSDOS/win16
applications]
- To multitask properly, and be more robust.
- To take up more disk & RAM.
- To stop appearing like an old-fashioned program.
- To escape many of the 64k limits of 16 bit programs.
- To have a program which runs well on modern CPUs and under Windows NT
- So your code has a future, and an easily maintainable one at that.
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]
- You've lost the source
- You depend on a third party DLL or VBX for which there is no 32 bit
equivalent. Partial fix: thunking
- You don't need any of the new API features our UI improvements.
- Your users will not gain much from improved multitasking or mind suffering
on a Pentium Pro CPU.
- You need to support legacy Windows 3.x systems.
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]
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]
This is a
fairly long story, which is partially documented in an appendix
[Top of
Section] [Index]
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? |
- Get a suitable computer.
- Get a suitable development environment.
- Get a decent book or two. Read them. And ideally an MSDN subscription
- Start writing Win32 programs, keeping those books handy
- Don't give up when things don’t work the way you intended.
[Top
of Section] [Index]
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
- Lots of hard disk: for tools and intermediate files. 4GB+ is nice. With 8
or more GB you can keep all 3 MSDN disks on a hard disk.
- A 1024x768 or larger display
- A fast CD-ROM drive for speedier document access
- Fast access to the Internet at sporadic intervals (tool updates)
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]
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]
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]
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]
- The class libraries are only a foundation: there is nothing wrong in using
the raw Win32 API.
- Use the on-line help. Everyone else does.
- 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.
- 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.
- Resource files (.RC) are really text files and sometimes are best edited
as such instead of with a resource editor.
- 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.
- 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.
- Allow about six months to become reasonably competent, but never think you
can stop learning.
[Top
of Section] [Index]
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]
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]
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]
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
- Don't waste time developing for the Posix subsystem. Try and use the Win32
API with the C/C++ run time libraries to make things seem relatively similar.
- NT5's object model is not too different from Unix's 'everything is a file'
world. Just use WaitForMultipleObjects() instead of select().
- For some reason message queues aren't waitable objects; MsgWaitForMultipleObjects() is a contrived way of including
one of these in the selection.
- You can't wait on sockets in Win95, only NT and Win98 with Winsock 2. Use
WSASelect() instead.
- When opening files with fopen(), don't forget the "b"
argument to indicate binary mode. Otherwise crlf translation will catch you
out.
- Beware of assuming case sensitivity in naming files. But using forward
slashes in path names is usually ok.
- Your C++ compiler should support STL quite happily, although you may need
some patches: the standard distributions are invariably inadequately tested.
- There is no fork(), and no real equivalent. Somewhere
in the NT executive it -and a process heirarchy- are supported, but they don't
make it as far as the Win32 subsystem. Threads and CreateProcess() is the best you can get.
- Don't expect signal() to work well either. It may be
in the run time library, but that doesn't mean that it works the way you
expect.
- If moving from a workstation environment, remember that the byte order for
x86 CPUs is not that of the rest of the world: use htons() and htonl() and the inverses
when doing socket work.
- There is no direct equivalent of a setuid bit for running programs.
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]
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 |
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]
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]
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]
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]
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]
This is an add on compiler and profiler
for Visual Studio. It's key features are
- C++ and Fortran compiler that knows about Pentium III floating point
registers and can generate code which makes use of them.
- Other compiler switches to do RISC-style aggressive optimisation
techniques such as loop unrolling and conditional moves instead of branching.
- 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]
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]
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]
Deserving a mention are
- Symantec C++
- IBM Visual Age for C++
These products exist, but do not get a
regular mention, something which may reflect their lack of popularity.
[Top
of Section] [Index]
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]
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]
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:
- Colin
Peters' Mingw32 project . this is the best place to start; it has pointers
to everything else you need)
- Cygnus Solutions' GNU-Win32
project
- The EGCS home page
- Mumit Khan's port of
EGCS to Win32
(thanks to Ross Smith of New Zealand for these
details)
[Top
of Section] [Index]
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:-
- Integration with development tools of choice (IDE, make files)
- Ease of archiving and retrieval of data.
- Integration with other parts of the development process: defect tracking,
web based delivery, and testing.
- Scalability to big projects in file, staff or duration terms.
- Multi-project file sharing and branching
- Support for mobile and remote users.
- Administrative tools and facilities.
- Reporting tools to keep the management chain happy.
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]
There are lots of
commercial, shareware and freeware products which can improve your product's
quality or development schedules.
Code analysers
- Compuware NuMega sell the Bounds
Checker tool which verifies all API calls, checks for invalid handles and
memory and resource leaks. It's not cheap but very useful: someone in a
project team should own a copy, and you shouldn't ship until the problems it
reports have been dealt with. The company's Soft Ice product line is for
serious hardware debugging.
- Rational Purify This is a competing
product to Bounds Checker.
- lint for the PC. This is a static
code analyser, which many Unix hackers will be familiar with. Reasonably
priced.
- Autoduck. A great little piece of freeware to generate documentation from
structured comments in your source -can be used to do HTML documents as well
as standard windows formats. [Search for this; its home moves around]
Other items to consider include:-
- Win32 "Platform" SDK.
Not a standalone compiler. But it does include
some useful tools. Nowadays downloadable from Microsoft's site.
- NT and Win9x Device Driver Kits.
You need these to write device
drivers. A download from MS
- The appropriate resource kit for your OS
Lots of handy utilities,
including the essential "windiff" application.
- Useful shareware
4NT, Hamilton C shell : new command shells to make
life easier.
- Emacs
Aficionados of this editor will need the NT Version
- Pencil and paper
Great for UI design, application architecture design
and note taking. Best backed up with a filing system and a routine of
reviewing past notes to question documented design decisions.
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]
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 |
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]
- 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.
- Hardcore 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]
- 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]
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]
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? |
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]
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.
- Has many consumer oriented extensions to the basic API.
- Only LOWORD of GDI co-ordinates are used, and many new GDI calls are not
implemented.
This is a side effect of the need to support legacy graphics
cards, printers and their associated 16 bit device drivers
- Client side named pipes only.
- No security APIs.
- Port I/O (_in() and _out())
works. For now; this may not hold in later versions builton the NT kernel.
- Threads can block on win16mutex.
This means while one app is busy in
the parts of the OS, the rest will get suspended when they make OS calls. This
isn't usually too noticeable, except in high performance/low latency
programming problems.
- Different file mapping semantics: all mapped files share the same address
in all processes.
- FreeResource() must* be called for every
resource loaded with LoadResource().
NB: OWL2.5 TDib
class doesn't do this.
- 32 bit apps can thunk down to a 16 bit DLL.
- BeginUpdateResource() and related calls do not work:
you can not modify EXE/DLL resources through API calls.
- Socket handles can not be used as file/system handles (in calls
such as WaitForMultipleObjects) (Winsock 2 removes this
restriction)
[Top
of Section] [Index]
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:-
- Full 32 bit GDI with clipping paths, and Coordinate Transform Matrices.
- Overlapped I/O
- Services API (like Unix Daemons)
- Can create server side named pipes
- No port I/O allowed from an application [you need a driver]
- Unicode support.
- Support for multiple processors.
- 32 bit apps can not call 16 bit DLLs.
- Real time threads and no app blocking on window resize/move
- Separate WOW subsystems means 16 bit apps can not assume that other 16 bit
apps share the same address space.
- Toolhelp32 is not supported.
- DirectX (DirectX 3.0 in NT4.0 onwards, Direct3D in software only with
service pack 3)
- NT4 adds "Waitable Timers" for better thread scheduling.
[Top
of Section] [Index]
Win32s is "Win32 for Win31", and
is a half way house between 16 bit windows and the 32 bit world.
- No thread support or pre-emptive multitasking: explicit Yield(), PeekMessage() and GetMessage() calls are needed to give other applications a
chance to run
- Comms, multimedia only through thunking down to the Win16 API
- VB4/32 , VB5 and VC5 applications do not run under Win32s.
- No console support
- Many thunked down functions have the old 16 bit semantics and not any
win32 extensions.
- All the restrictions of the win95 implementation also apply
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]
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:-
- Unicode APIs only.
- New UI controls to make efficient use of the display
- In-process COM support (not in version 1)
- No MoveTo() or LineTo. Use PolyLine.
Expect a new release of the OS annually
-at least until the end of the century. [Top
of Section] [Index]
- 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]
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]
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
- Note that Win64 Pointers are eight bytes long, not 4. So casting between
DWORD and VOID* is no longer acceptable.
- There are extra typedefs for ints and longs that are pointer sized and can
be used for arithmetic.
- 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.
- Don't include any x86 assembler or machine code -or keep it in a module
with replacement implementations in your language of choice.
- Stop trying to write dual mode win16/win32 code. You probably won't regret
it.
- Be careful of #ifdef WIN32 sections intended to hide
features from a 16 bit build catching you out on a WIN64 build.
- 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.
- 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.
- 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]
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 |
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? |
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.
- Get the 32 bit version of your development tools
- Get the 32 bit versions of any support DLLS/VBXs
- 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]
- 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]
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]
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]
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]
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
- a saver is just an executable (.EXE) with a .SCR extension
- the setup dialog is invoked with a /c argument; otherwise the app just
shows the saver.
- when invoked with "/p hwnd" then it's preview mode
- 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]
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]
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]
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]
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]
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]
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]
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]
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]
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.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? |
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]
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]
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]
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]
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]
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.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? |
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]
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]
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 functions:- GetCommModemStatus(), SetCommState(), SetCommMask(), SetupComm(),
PurgeComm(), ClearCommError(), SetCommTimeouts() and EscapeCommFunction()
Tips:-
- Even on Win9x, you can use overlapped IO with a com port
- The Signalled state of a port seems to indicates it is ready for reading
or writing, even if you only opened the port unidirectionally.
- WaitCommEvent() lets you block waiting for something
interesting to happen, such as data arriving or various lines (e.g. RI -Ring
Indicator) toggling.
- On win98/NT5, RequestDeviceWakeup() may even
let the external port wake up your app -especially if RI is used as the
signal.
[Top
of Section] [Index]
Open it as
per a serial port, using "LPT1" or "LPT2" as the port name. This works provided
the device which you are talking to uses the standard ECP/EPP protocols. If you
are trying to use the parallel port as a non standard IO port, then you have to
access the port using port IO instructions -something you are not mean't to do
from a user mode application, and may not be able to do reliably even in a
driver a couple of years from now.
[Top
of Section] [Index]
Getting a user mode thread to respond to a signal even in
20mS or less on a Win9x box is an achievement, so use of NT is the first step.
Next set your process as real time, and give the thread a high priority.
Finally, play with timeBeginPeriod to see if increasing the
RTC interrupt frequency helps. Even with all these tricks, a heavy load on the
system can mean that your thread doesn’t get scheduled for tens to hundreds of
milliseconds.
Locking down memory with VirtualLock helps to ensure
that memory isn't paged out, which can make response time worse. The app/user
needs SE_INC_BASE_PRIORITY_NAME rights to be able to do this. In practise it is
of little benefit. Maybe the new AllocateUserPhysicalPages() call in NT5 will work better.
[Top
of Section] [Index]
Not
as far as the authors of the comp.os.realtime FAQ are concerned. The lack of
priority inheritance can make priority inversion deadlocks possible, and there
are not enough process and thread priorities for their scheduling needs. Neither
Win9x or NT are very good for time critical user mode code. Win9x, lacking a
re-entrant Win16 subsystem, cannot be used very deterministically. (I.e. you
can't predict whether or not you thread gets locked out from a many API calsl).
Win9x should certainly be avoided for time critical code -unless you want to
write assembler routines in VxDs, whose their time to respond to an interrupt is
very deterministic.
Windows NT does have real time priority process and threads, which can be
used to get as close to real time as you can hope to do with a Windows app. It
can be used more easily for "soft real time" applications; its interrupt
handling architecture (interrupt handlers should just schedule deferred
procedure calls) make hard real time tasks (such as soft modems) hard to
implement reliably. Embedded NT sounds like NT tweaked to treat {masked,flash}
ROM as memory so that diskless and displayless operation is possible: no
scheduling changes apparent.
WDM is emerging as a single driver model for new bus (1394, USB) drivers on
both platforms. The related video handling driver architecture "WDM Streaming"
could be useful not just for time critical video processing, but also as a way
of gluing together other high bandwidth kernel mode data sources and sinks.
Windows CE has some potential as a light weight Win32 platform for embedded
use. However there is a fundamental problem in the Win32 system architecture:
applications and device drivers are cleanly split. This is great for hardware
independent applications, and application independent hardware, but not so good
for anyone trying to write a custom application coupled directly to a piece of
non standard hardware.
DOS, DR-DOS, and RTOS products like QNX
and VxWorks may be better for your needs. There are stated plans for CE to
evolve to become a hard RTOS, but as this platform's evolution seems to follow
the needs of high visibility product categories (WebTV, HP/C, Dreamcast &
others), it is hard to predict when CE will reach this state.
[Top
of Section] [Index]
You can use SetWindowsHook to do this, but need to
put the hooks into a DLL which is then mapped into the address space of all
applications. Richter's book covers this process.
[Top
of Section] [Index]
There are
lots of ways of measuring time, each with their own advantages and
disadvantages. Variables are accuracy, portability, overhead and ease of use.
- time
- part of ANSI standard C, found in time.h and
measuring seconds since 1/Jan/1970. Works reliably until some time in January
2038. Portable, and good for both external displaying (via ctime) and for arithmetic. Also integrates well with time
zone settings. Not useful for dates before 1970.
- GetTickCount
- Returns elapsed CPU tick count to nominally millisecond resolution. On
Win9x, the minimum resolution is 55mS, on WinNT it is usually a smaller value
(such as 10-15 mS). Wraps every 49 days, and bears little relation to the
outside world. Laptops and OnNow PCs may suspend the timer while in
some sleep states. A call to timeBeginPeriod to increase
the timer interrupt frequency makes this function more accurate.
- GetSystemTime
- Returns system time in a fairly complex SYSTEMTIME structure. Converting
it to a FILETIME format makes comparisons and differences easier. The
resolution is no better than that of the GetTickCount
call: 10 or 55 mS. This time format won't wrap around for millenia, which
makes it ideal for persistent data.
- QueryPerformanceCounter
- A higher resolution counter, whose frequency and accuracy varies from OS
to OS, and from CPU to CPU. You need to use QueryPerformanceFrequency to discover the frequency. On a
single processor NT platform the counter frequency is 1+ MHz, so is accurate
to microseconds. On a multiprocessor system it uses the RDTSC opcode to measure CPU clock ticks. Good for low level
performance measurement, although the switch to kernel mode adds enough
overhead to hamper profiling of small routines.
- rdtsc
- The Pentium's "Read Time Stamp Counter" instruction is what NT4's Multiway
HAL's version of QueryPerformanceCounter must use. If
inserted inline into code, you end up with an application which will break on
a 486 or earlier. But it does measure CPU clocks with the least amount of
overhead, so can be used in non release profiling builds on Pentiums and
later. Theoretically If you use this on a multi CPU system you can get into
trouble, as each CPU has its own clock, but in practise they seem to be
synchronised to a few ticks. Portables can be ever wierder -they can suspend
the clock or change frequency on the fly.
There is also the MFC CTime structure, with a CTimeSpan
function to measure elapsed time. These classes exhibit "unusual" behaviour when
measuring the time spans between two dates with a transition to summer or winter
time between them. Being based on the ANSI time()
functions, they have the same weaknesses of only being valid from 1970 to 2038
[Top
of Section] [Index]
This may seem a minor
area, but it can often contain some of the hardest programming problems Windows
has to offer. Things that are both commonplace and simple to interact with, turn
out to be programming nightmares to implement. And don't expect the SDK or class
library to give you everything on a plate: a lot of hand crafting is needed to
make a good UI.
5.4.1
|
How do I create/use Shortcuts (.lnk files)? |
5.4.2
|
What are shell extensions? |
5.4.3
|
How do I get the shell to automatically create new documents of my
type? |
5.4.4
|
Why doesn't my app have nice 16x16 and 48x48 icons? (aka: Why does my
app still have the MFC icon?) |
5.4.5
|
How I put my application into the start bar |
5.4.6
|
How do I hide my window from the task bar? |
5.4.7
|
How do I get Internet Explorer/Office 97/Win98 menus & toolbars?
|
You
have to use IShellLink to manipulate these. To invoke the shortcut, use ShellExecuteEx(): ShellExecute() does not
work on all link types -e.g. dial up networking links.
[Top
of Section] [Index]
These are in-process
COM objects which implement a sparsely documented set of interfaces (see
MSDN/MSDN on the web) and enable anyone to write their own "folder" within the
Windows Explorer shell
[Top
of Section] [Index]
By adding a shellNew handler. The default
is to get the shell to create a zero length file of the appropriate name. Your
application's file loading code must handle this case and treat it as creating a
new blank but named file, instead of as an error.
Note that although this is a Win95 integration guideline, it is now often
considered good form to ask the user if they actually want you to extend their
shell in this way -as once you have 20+ applications installed, that pop up menu
ceases to be too useful.
[Top
of Section] [Index]
Because you haven't written
any. Use your icon editor to create new device images of the appropriate size
within each existing icon. Then update your windows by using either RegisterClassEx or WM_SETICON. The latter
is a message which can be posted to any window to get it to change its icons and
is very useful for dialogs and other situations where the class is registered
out of your control.
When the MFC App wizard is used to generate an application, it generates
16x16 and 32x32 icons: you need to modify both when customising your program.
[Top
of Section] [Index]
Those
little icons at the end of the start bar are called tray icons, and should be
used sparingly. Too many applications take up the tray with clutter, and the
latest Windows UI guidelines advise very strongly against joining in.
To find out how to create one, look in the manuals for the Shell_NotifyIcon() API call. This lets you add new icons to
the tray. Also register a handler for the message "TaskbarCreated" which is sent
out whenever IE4 restarts, and recreate the icon after such an event.
MSJ March 1995 has a good article covering the whole subject, although sadly
it is no longer in the MSJ section of MSDN. Otherwise see "Adding and Deleting
Taskbar Icons" in MSDN or the "Programming the Win95 User Interface" .
[Top
of Section] [Index]
A window will show up in the taskbar button area
if
- The window is visible
- The window is not a child window.
- The window is not owned.
- The window is not a tool window.
There are some exceptions to the above rules, but they apply only to legacy
("designed for Windows 3.1 or earlier") applications.
To make your application minimise to a tray icon: hide it when you get the
WM_SYSCOMMAND message requesting a minimise; restore it and bring it the
foreground manually.
[Top
of Section] [Index]
You can do these with the Rebar/Coolbar common control,
available from the COMMCTRL.DLL library distributed with IE3 and IE4.
Documentation for using this control comes with the Internet SDK, and VC++ 6.0
Note that once you use this control, you end up in a complex situation
regarding redistribution: for pre IE3/IE4 users you have to redistribute a common
controls update. This is simple, but if the update was applied does add a
reboot to the installation process. Alternatively, design an application which
only uses the rebar if the library is up to date, and drop to the previous
version if not.
[Top
of Section] [Index]
There are lots of ways to "Internet Enable" an application, from the simple
one of opening up URLs in the default web browser, through Winsock and WinInet
right up to integration of URL monikers and asynchronous pluggable protocol
handles.
The Internet Client and Platform SDKs contain the document all the
techniques. No-one ever asks questions about the really complicated methods , so
either they are rarely used or the people who use them are very smart indeed. If
you are just starting out then stick to Winsock WinInet and the Web Browser
ActiveX control.
The Winsock
FAQ covers a lot of the low level sockets questions, and includes sample
code too.
6.1
|
How do I open a URL in the default web browser? |
6.2
|
How do I programatically download files? |
6.3
|
How do I write a Web Browser? |
6.4
|
Where is the standard of HTTP/FTP/SMTP/NNTP/some-other-protocol
documented? |
6.5
|
How do I write raw sockets programs (like ping)? |
6.6
|
How do I programatically connect to the net? |
6.7
|
How do I tell if a machine is connected to the Internet? |
6.8
|
How do I get a machine's MAC address? |
6.9
|
How do I get a machine's IP address and hostname? |
6.10
|
How do I display a JPEG or GIF file? |
This is easily done by calling ShellExecute() HTTP
and FTP URLs should be processed by both Netscape and IE: the "default" browser
will handle them. Other protocols such as mailto and news may also handled by
the browser. IE4 adds handlers for things like "Callto:" for Net Meeting
contacts. #include "windows.h"
//include ShellExecuteA
#include "shellapi.h"
//link in the library
#pragma comment(lib,"shell32.lib")
int main(int argc, char *const argv[])
{
ShellExecute(NULL,"open", "http://www.iseran.com/", "", "c:\\", SW_SHOWNORMAL);
return 0;
}
NB: Some versions of Netscape do not reliably set up the appropriate registry
entries: see an article in Windows Developer Journal for
details and workaround to this.
[Top
of Section] [Index]
With the
WinInet DLL and API (and MFC wrappers), MS have provided us developers with a
relatively easy to use set of APIs for retrieving files using any of the known
Internet protocols. A nice feature is that these calls make use of the Internet
Explorer cache. A weakness is that they rely on IE3 or later being installed on
the machine, which is almost universal nowadays.
[Top
of Section] [Index]
You don't if you can
avoid it: you build an application which uses the MS Web browser ActiveX control
and provides its own menu and toolbars. This gives you state of the art
functionality in an afternoon's work. Note that the Browser control is much more
idiosyncratic than commercial ActiveX controls, and it can take some time to
fully understand it. That's why a whole afternoon will be needed.
Alternate methods exist but are harder work:
- Take the Netscape source and somehow integrate it with your program.
- Buy the Sun HTML Java bean. Portable, but flaky.
- Talk to vendors such as Spyglass.
[Top
of Section] [Index]
All official
internet standards are documented on the net itself, rather than in win32
manuals. The Internet Engineering Task Force
is a good starting point.
[Top
of Section] [Index]
This is very difficult, with implementation specific APIs provided for
some Win32 platforms. For NT, look for ICMP.DLL and associated documentation in
the Win32 SDK. Also consult the Winsock FAQ
[Top
of Section] [Index]
Automatically, if the user has the appropriate dial-up settings and
your application makes a call which goes out over the network. Otherwise, ShellExecuteEx() can be used to open a dial up networking link
file.
The IE4 version of WinInet adds functions like InternetGoOnline(), InternetAutodial()
and InternetAttemptConnect() , all in an attempt to
make life simple. In fact, they make things more confusing as you have to know
which to use and in what order. InternetAttemptConnect()
seems the best bet.
[Top
of Section] [Index]
There is no single function for determining if a machine is connected
to the Internet, and it is impossible to reliably determine what is happening
without side effects -such as automatic network connections taking place. What
you can do is reliably detect when there definitely isn't an Internet
link: in the absence of any dial up or LAN connection the system is definitely
on line.
Some techniques include :-
- RasEnumConnections() . A reliable technique for
modems and direct dial up networking, but not for situations where Internet
access is via a LAN. You should dynamically load "RasEnumConnectionsA" from
"RASAPI32.DLL", as LAN installations of Windows may not include the library.
- InternetGetConnectedState() : a Wininet/IE4 function
call. Can distinguish between modem and LAN, but can't handle complex
LAN+autodial router situations. It is "offline state aware". Important:
handling of the off line flag changed for IE5 -it returns TRUE for connected'
even when off line, but signals the flag in the LPDWORD parameter.
- InternetCheckConnection() : a Wininet/IE4 function
call. This is meant to determine if a URL is reachable -in practice it is
pretty unreliable and best avoided.
- Using the Offline flag which is part of IE4 to allow users to manually
control the online/offline state of applications. This flag is stored in the
registry and can be manipulated via some new function calls
- WM_DEVICECHANGE messages, which tell your app when a slow or fast network
adapter has arrived or departed. There is no way to tell if the adapters are
actually connected to anything though.
- NT4 SP4, NT5: The IP Helper API can tell you which network 'interface' to
use to connect to a supplied IP address, and what the bandwidth and current
status of that link is.
These calls mostly determine the presence or
absence of network connections -not Internet access, so can't handle a home
network sharing a dial up connection, or two laptops connected directly to each
other.
The global offline state flag of IE4 (and hence win98, NT5) and the call to
test it - InternetGetConnectedState()- look the best long
term options, but will take time to become universal. The IP Helper APIs even
let you find out how much traffic is going over a link, but only detect the
'loopback' interface on Windows 98, so is not a lot of use. Wouldn't a
'GetSpeedToHost() function call be great?
Finally, whatever technique you use, when it's time to talk to a remote site,
always add timeouts or a cancel button. Even a quick functions like gethostbyname() can lock up an app if something in the network
chain is broken.
[Top
of Section] [Index]
Not all
machines have a real MAC address, only those with LAN cards. Given that fact, an
NdisRequest() for OID_802_3_CURRENT_ADDRESS will give you the right answer,
provided the NetBIOS protocol stack is installed on the PC. This used to be
common on Win95 boxes, but with Win98 and NT installing TCP/IP as the default
stack, it is becoming rarer.
NB: The OLE function CoCreateGUID() will try to create a
unique GUID, the last 64 bits of which are usually the MAC address of a
card on the PC. Do not rely on this 100% of the time, as the algorithm does
other things when running on a PC without a network interface.
[Top
of Section] [Index]
The IP address can be tricky, as a PC with multiple network interfaces
(such as LAN and modem) will have multiple IP addresses. Furthermore DHCP and
dial up networking allow systems to change their IP address on a regular basis.
The hostname is more constant than anything else, and a call to gethostname() will return this. gethostbyname() can take this name and return a list of its IP
addresses. What you actually get back varies from machine to machine -and, on a
laptop hor home system- from minute to minute.
[Top
of Section] [Index]
In C++ this
is not always easily done for free, as no one of the standard class libraries
automate this. Using an ActiveX control which can handle the formats is one
option -and such controls often ship with the professional versions of
development products. Check the redistribution license before use, as you may
have to pay distribution fees.
GIF is -relatively- easy to parse, especially compared to JPEG, although
UNISYS require upfront licensing fees before you redistribute commercial,
shareware or freeware applications using the file format. This is because they
own a patent on the LZW compression algorithm used.
Windows 98 and NT5 will decompress a JPEG for you, provided you create a
bitmap BITMAP with the right flags and point it at the compressed image in
memory. For Win95 and NT4 you have to roll your own solution. Most people use
the C source from the independent JPEG group
NB: Java and IE can both display JPEG and GIF images, and can be made to
render the images within your app via ActiveX, although it can be tricky to
integrate such a solution. The royalty issue of using either of these tools for
GIF display within your own products is "unclear".
[Top
of Section] [Index]
7.1
|
What is a DLL? |
7.2
|
Why would I need to create one? |
7.3
|
How do I create one? |
7.4
|
How do I export functions? |
7.5
|
How do I load a DLL? |
7.6
|
How do I debug a DLL? |
7.7
|
How do I create C++ classes in a DLL? |
7.8
|
Why does my MFC-based DLL only work in some applications? |
7.9
|
I have a 3rd Party DLL with no documentation: how can I use it?
|
It is a collection of functions
which do not constitute a process, but which can be loaded into a process and
invoked. The loading is done at run time rather than at compile time (those are
static libraries). DLLs have a special entry point DllMain
which is invoked when processes and threads are attached and detached, allowing
data structures to be created and destroyed appropriately.
A lot of the system is implemented in DLLs, even though their extension
changes somewhat. The file types OCX, CPL, DRV are all really DLLs.
In Windows 2.x and 3.x each DLL had only one instance of its data segment
regardless of the number of applications using it. In Windows 32 a DLL can be
marked as shared, for the same behaviour, but the default is for each
process to have a private copy of the DLLs data.
[Top
of Section] [Index]
- To divide a program into separate modules which can be loaded on demand.
- To store language/region specific resources
- To enable a core code library to be used by your own and other
applications
- To produce in-process COM objects, or an ActiveX control (OCX)
- Implementing OLE objects as in-process DLLs is the best way to get
performance out of an OLE link.
- To implement a control panel extension or some types of driver.
[Top
of Section] [Index]
By setting the options in
your compiler's IDE to generate a DLL rather than an EXE. You also need to
replace WinMain with a DllMain function.
[Top
of Section] [Index]
In win16 you needed to
add FAR EXPORT to all exported DLL functions. This is not required in win32.
Many 32bit compilers provide the function 'decorators' declspec(dllexport) and declspec(dllimport) to be placed in front of function
declarations to replace this call.
It is important to remember to put extern "C" {} around
function declarations to turn off C++ name mangling if you wish to have them
usable by any application other than those created with the same compiler.
Visual C++ now uses the stdcall naming convention, which adds a number to the
function name to indicate the number of bytes expected. This can complicated
importing functions in some languages (I.e. delphi). Either look at the DLL to
determine the extended name and import that, or create a .DEF file which
explicitly renames the functions.
If you are doing COM development then things are "different": you need to
export a method of accessing the class factories, another to determine if the
DLL is no longer needed, plus optional functions to register and unregister the
library in the registry.
[Top
of Section] [Index]
- Implicitly by creating an import library with IMPLIB.EXE
and then linking this library with the application.
- Explicitly with LoadLibrary() and LoadLibraryEx()
- Automatically with CreateDC() for printer and display
drivers.
- Magically with CoCreateObject()
If you use LoadLibrary() then a call to SetErrorMode() first can be used to let your app know of a
load failure without a dialog box popping up.
[Top
of Section] [Index]
By debugging the application
which loads the DLL, even though the debugger may complain about its lack of any
debug information: set breakpoints in your DLLs source and continue.
Writing a special test harness in the same language as the DLL can often
simplify the debugging process when the DLL is really intended for use by
another development tool or language.
[Top
of Section] [Index]
Do this very
carefully.
You can't mix C++ classes between vendors- the different name mangling and
object creation schemes prevent this. Use C functions or create COM objects
instead. Also make sure that exceptions are not thrown from the DLL to the app,
as stack unwinds can be disastrous.
You can implement C++ classes in a DLL when used within a C++ application
built with the same compiler. You can still end up with heap corruption if you
mix run time libraries: both app and DLL should use the same debug versus non
debug CRTL. Better still, always let the DLL create and free the memory used by
the object. Use the declspec(dllexport) and declspec(dllimport) decorators in front of your class
definitions in header files. Use something like #include
"pushpack4.h" at the start and #include "poppack.h" and
finish of the class header file to ensure that structure packing is consistent
[Top
of Section] [Index]
You may have created A DLL with the "Use MFC in a shared DLL" option.
This creates DLLS which can only be used within another MFC application. Change
to using the static MFC library instead.
[Top
of Section] [Index]
It may not be possible to reuse someone else's DLLs. Firstly, it is
often prohibited by the licensing agreement of the software. Secondly, it is
pretty hard to work out how to use many DLLs.
Quickview or other DLL viewers can list the exported functions of a library,
but they provide little or no information on what parameters must be supplied,
or what those parameters mean. Furthermore inproc COM objects are not listed
among the exports, as pointers to their exported functions are returned by the
factory objects.
For progress any further you will need a dissassembler, a debugger and
patience. Within the European Community it is actually legal to reverse engineer
the interfaces to another program provided this is done in order to facilitate
the development of compatible products. However the exact details on this
pro-competition law are complex: consult a legal expert before attempting to
take advantage of it.
[Top
of Section] [Index]
8.1
|
What is a console application? |
8.2
|
Why write a console application? |
8.3
|
Why shouldn't I write a console mode application? |
8.4
|
Why doesn't SetTimer work in a console app? |
8.5
|
Why don't asynchronous socket calls or the MFC CSocket classes work in
a console app? |
A console
application is a windows application, plain and simple.
They have a different flag in the executable header to indicate a win32
character subsystem application, which the OS recognises and knows to create a
new console window unless the application is executed from an existing console
window.
C & C++ Compilers usually bind the entry point of a console mode app to
int main(int argc, char *argv[]) and stdin, stdout and
stderr bound to the console. Otherwise, there are no real differences. A console
application has access to the entire win32 API, can create visible or hidden
windows, and generally do what it wants within the win32 environment.
Windows NT has a whole console API, enabling applications to interact with
the user within the confines of the console window. This is often used by
console based editors.
[Top
of Section] [Index]
It's an easy way
to start porting an application from Unix or similar OS to Win32. It's also a
simple way to test and demonstrate aspects of Win32, without having to worry
about window creation or management for text output.
If you want to write programs specifically for console users, then console
mode applications are the only way to do it.
[Top
of Section] [Index]
- Windows95 doesn’t properly implement the whole win32 console APIs, or even
display the icons of console applications in the explorer reliably.
- When a console app is started from outside a console, the OS always
creates a console window for output: this is often undesirable.
- Many Windows API calls expect a the calling application to have a message
queue and a window somewhere.
- If you want to have a console for debugging output, then you can just
create one with AllocConsole(). One trick is only to
create these consoles in a debug build, or when a special registry key is set.
You can easily use WinMain() as the entry point
to an application which intends to create no windows, enabling the application
to start cleanly from the explorer.
[Top
of Section] [Index]
All SetTimer does is tell the system to stick WM_TIMER messages into your window's/thread's message queue
after all other messages have been processedand the timer has expired: DefWindowProc secretly invokes the function when it gets this
message. Lacking such a queue or a GetMessage()/DispatchMessage() pumping loop the messages never
get delivered.
Use Sleep(), WaitForSingleObject()
and Waitable timers instead
[Top
of Section] [Index]
Again, because windows need to be
created to handle received messages. Creating a hidden window is the workaround
here -or use blocking sockets instead.
[Top
of Section] [Index]
9.1
|
What is a service? |
9.2
|
How do I create one? |
9.3
|
How do I start/stop/install/uninstall a service? |
9.4
|
How do I debug a service? |
9.5
|
How does it gain the same rights as a user? |
9.6
|
How do I change the parameters of a running service? |
9.7
|
How do I run an existing program as a service? |
9.8
|
How do I run a service under Win95? |
It is a process which can run
on an NT box without a user being logged in, effectively acting as a user mode
part of the operating system. It is similar to a Unix Daemon.
One strength of the service model is the way they can run on a machine
continuously, another is that the service control manager can be controlled
across the network, so services can be started and stopped remotely. A third
advantage is the rights of the service can be different from those of any logged
on user, so that it can do things which are not otherwise possible.
There are weaknesses. Services can not directly interact with the desktop
unless they are an "Interactive Service" executing from the local system
account. (*) Some of the functionality which services can perform is restricted
because of this -for example prior to calling COM objects in a service prior to
NT4 was barely possible. Services are NT only applications, so a product which
aims to support Win9x and NT will have to provide different programs.
(*) Services can always pop up a message box with the MB_SERVICE_NOTIFICATION flag. But remember, on a real server,
there is often no-one at the console.
[Top
of Section] [Index]
The Win32 platform
documentation covers the basics of creating, installing, configuring and using
services -this is an essential read.
There is some sample code in the Win32 SDK, and the Microsoft Java SDK
includes the information and samples to build a Java service.
[Top
of Section] [Index]
The NET START and NET STOP command lines can be used to start/stop
services, or they can be started from the control panel.
The service control utility (SC.EXE) which comes with the Win32 SDK is
probably the most powerful way of controlling services from the command line
during development.
[Top
of Section] [Index]
If your IDE lets you
attach to a running process, you can attach to a service already in execution. A
DebugBreak() entry in the code (or anything which raises an
unhandled exception) will also cause your chosen JIT debugger to start up.
Another trick is to have your main() function recognise
a "-debug" parameter and provide a test harness to the core functions you wish
to debug -this lets you get code working without having to worry about the extra
life cycle complexity of a full service.
[Top
of Section] [Index]
With
the functions LogonUser() and ImpersonateUser()
[Top
of Section] [Index]
Not easily. The registry should be used to store configuration
information, so the service would have to regularly check for the appropriate
registry entries changing, or respond to a "reread changed parameters and
restart" message somehow passed to it.
ChangeServiceConfig() is used to change the operational
parameters of any service which the OS cares about.
[Top
of Section] [Index]
There's a program in the NT resource kit which will let you do this, to
a greater or lesser degree.
[Top
of Section] [Index]
This is not
possible; the best substitute is the list of registered apps under
HKLM\Software\Windows\CurrentVersion\Run or RunServices. Once your app has been
started, it must call RegisterServicesProcess() to tell the
OS it wishes to stay active after a user logs off.
Warning: win9x "services" may not get executed until someone is actually
logged on.
[Top
of Section] [Index]
Getting your program to build can be hard, especially when you are just
starting out. Most of the problems are relatively simple -it just takes time to
learn what they are and how to react.
10.1
|
The compiler can't find functions which I know are in Windows.h |
10.2
|
I get compiler errors when I try assign a C++ member function to a
Windows callback routine. |
10.3
|
I get 'unknown symbol' errors when linking |
There are a number of common reasons for this.
- Your code has VC_EXTRALEAN or WIN32_LEAN_AND_MEAN defined, and the symbols you want are
not in the 'lean' subset
- The functions you want are actually in a different header file: a quick
search can test for this. Example: ShellExecute is in SHELLAPI.H
- The function is a recent addition and your Win32 headers are out of date.
Try downloading a later version.
- The function is a recent addition, but you are not telling the compiler to
include it. You need to define _WIN32_WINNT as 0x0400 for
the NT4 extensions, 0x0410 for Win98 extras, and 0x0500 for a full NT5 header
set.
- In C++, a local implementation of a function may hide the base API
implementation. Preceding a function such as SendMessage() with double colons "::" will give you the base
API call.
- Last, but definitely by no means least, you may have misspelt the
function, or got the capitalisation wrong.
[Top
of Section] [Index]
There is a very simple reason
for this: you can't use non static member functions as callbacks. All such
functions have a pointer to the 'this' object added as a first parameter, so
that the function knows which object it belongs to. OS callback functions
-WndProc, TimerProc, Enum*Proc and the likkkke- do not have these pointers, so
member functions can not be cast.
Static member functions can be used. If you can store a pointer or reference
to the C++ object with the the Windows callback (or attach it to the Window for
a WNDPROC), then these static functions can be used to invoke the C++ member.
This is how most C++ class libraries work, except for the really devious ones
that create a lump of code on the fly to do the dirty deed (a thunk is the
technical name)
[Top
of Section] [Index]
This
means that the linker needs to link to a library/object file to invoke a
referenced function. There are a number of causes for this.
- Check you are including all the relevant libraries -such as WINMM.LIB and
WSOCK32.LIB, needed for multimedia and sockets, respectively.
- The calling convention/name mangling on the exported function may
different from what you expect, so the routine is not being found. C functions
need to be declared as extern "C" {} to stop the C++
compiler corrupting the name -but even C functions which use the stdcall
calling convention include a parameter size flag in the imported/exported
name.
Sometimes you don't even have a matching LIB file for a header file:
this is usually the case with DLLs. The tool IMPLIB can create a library file,
or LIB.EXE itself in Visual Studio 97 and later. There is also the brute force
solution of run time linking with LoadLibrary. This is inelegant but very
effective.
- If the unknown symbol is main() or WinMain, then the cause is usually you are providing a
different entry point to yor application from that which it expects. Either
fiddle with the compiler settings till the linker knows what entry point to
look for, or use the expected entry point.
- Finally, if it is beginthread,
beginthreadex, and endthread that are missing, then
you are linking to the single threaded C library but parts of the app expect
the multithreaded equivalent. Change the run time library settings.
[Top
of Section] [Index]
Debugging: the process of discovering how many invalid assumptions you made
during the design and implementation of your program.
It can be hard to get anything working when you are just learning Windows:
not only is there a lot to go wrong, the debugging tools and techniques are all
foreign. Worst of all, there are a lot things you don't understand, which can
lead to serious flaws in your code.
With time you will get better at debugging. But remember: it is often better
to be able to write working code than to be good at finding fixing broken code.
11.1
|
My application keeps on stopping with "an unhandled exception C000005"
|
11.2
|
What is Just In Time Debugging? |
11.3
|
What do all those exceptions mean? |
11.4
|
What is SEH and how do I use it? |
11.5
|
Why does a Win32 API call keep failing? |
11.6
|
How do I print a message to the debugger? |
11.7
|
How do I break to the debugger? |
11.8
|
NT Crashes with a Blue Screen of Death when my program runs! |
11.9
|
My STL code does not compile/work! |
You have a bug. This is the 32 bit equivalent to
Exception 13: General Protection Violation. The NT kernel will also raise
it when an application has done something wrong which it has detected: invalid
arguments [checked build only?], overwriting the guard bytes at the end of GlobalAlloc()'d memory & the like.
[Top
of Section] [Index]
It is a feature
of windows95/NT where a debugger can be attached to a process after an exception
has occurred, and is very useful for debugging your applications. It is less
useful when developing with more than one compiler/debugger combination, or when
you end up starting to debug third party applications.
It is controlled by the [AeDebug] section of win.ini in Win95, and in the NT
registry section
HKEY_CURRENT_USER\Software\Microsoft\Windows
NT\CurrentVersion\AeDebug
Auto: REG_SZ "0" or "1" : Set to "1" if you want your debugger to run
automatically
Debugger: REG_SZ: the command line to start the debugger, which is used as a
printf argument and should contain two %ld strings to be replaced by the process
ID and exception number.
E.g. "Windbg -p %ld -e %ld"
[Top
of Section] [Index]
See the separate list
of exceptions
[Top
of Section] [Index]
Structured
Exception handling is a formalized, cross language method of raising and
processing exceptions. It can be used to make your application more robust or
crash more gracefully. At its simplest, an SEH handler around an application can
be used to ensure that no matter how the C/C++ program exits or crashes, the
program has left external files and devices in a stable state.
At its most advanced, it can be used to implement innovative coding
techniques such as sparse arrays and expandable shared memory heaps. Jeffery
Richter's book covers the topic in significant detail. Note that most programs
don't attempt such advanced SHE tricks.
SEH is very similar to C++ exception handling, and the two can both be used.
The C++ handler catches exceptions raised by C++ libraries, COM interface
wrappers and the like, while the SEH handler will catch the really low level
stuff like pointer faults, illegal instructions and other symptoms of a slightly
substandard program. Logging and cleanup routines can still be called, but you
need to make no assumptions about the state of the program and attempt as little
as possible. The worst case to deal with is usually something like an SEH
exception in the destructor of something important like the application object.
__try {
try {
//app stuff here
}
catch (...)
{
//C++ exception handler
}
}
__except (ExFilter(GetExceptionCode(),GetExceptionInformation()))
{ /* … */ }
[Top
of Section] [Index]
If a
Win32 function call fails, then GetLastError() will return
a DWORD value describing the error. A call to FormatMessage() can often turn this into an error string, from
which the cause of the error may be determined. The header file "Winerror.h"
contains the definitions of the standard errors.
Some common reasons for a function call failing are
- The function is not implemented on that version of Windows ( GetLastError()==120); ERROR_CALL_NOT_IMPLEMENTED
- You passed in arguments which failed the parameter checks. A common
mistake here is failing to fill in the dwSize or cbSize member of a data
structure with the full size of the structure as returned by sizeof()
- The object you are working on is in the wrong state. I.e the socket is
unbound, or a handle refers to an object which is now closed.
- You are trying to do something which is simply not possible. This may be
due to limitations of the systems you are using, or mistaken assumptions on
your part.
When starting off, you may get frustrated at the number of
things which don’t seem to work, and blame the tools and platform. With time,
you will learn more about the API, and you realise that is many your assumptions
are broken and not the platforms. Once you reach this state, then you can spend
ages looking at a broken routine before discovering that it really is the API
Call which is not working as specified. A check through the MSDN disks and
on-line knowledge base is often invaluable at this point.
[Top
of Section] [Index]
With
the OutputDebugString() function. Compilers and class
libraries usually include macros to perform printf style formatting and to omit
the output when a release build is generated.
[Top
of Section] [Index]
Use the DebugBreak() function, which will break to the debugger
somewhere in the OS. A couple of steps over assembly language statements and
you'll return to your code.
The statement: _asm { int 0x03 } does the same thing on
x86 systems, and lets you skip having to step out of the OS.
[Top
of Section] [Index]
This should not happen -and when it does, it is either the result
of hardware problems on that system, or due to a bug in the OS or third party
drivers.
Microsoft maintain a list of
errors to help you understand what is going on. However, it does not always
help you to solve the problem.
Try to produce a small piece of code which replicates the problem: the easier
it is to replicate, the easier it is tracked down. If you can track the BSOD
down to a particular driver then get in touch with the support group of that
organisation. Yes, even Microsoft support, if it is clearly part of the OS. Also
check the companies' on line support pages to see if the problem is already
known.
[Top
of Section] [Index]
This is more
common than you'd think with Visual C++, and it stems from the fact that the STL
library on the product was one licensed from a third party a few years and then
seemingly broken in the pursuit of some incomprehensible goal. The early
releases of this library (in VCC4.x) were dire: Strings leaked, dequeue crashed
on adding the ninth element, you name it, it broke. Today it is somewhat more
stable, but not as good as commercial products from third part vendors,
including that available from the original supplier of the VCC implementation.
Patches for the VCC distribution can be obtained from the supplier DinkumWare
[Top
of Section] [Index]
Shipping: the process of delivering working code to customers. Ideally this
should take place after "debugging", although there is almost invariably a bit
of overlap. A decent QA process, in which the purpose of a test is defined as
An input sequence designed to show the presence of bugs is what is often
omitted. It is a lot easier to test when the overall goal, and hence tests, are
designed to show the absence of bugs -but that just hides problems till the
product gets into the hands of end users.
12.1
|
What do I need to do before I ship my program? |
12.2
|
How do I determine which DLLs are needed? |
12.3
|
Help, my release build won't work, although the debug build does!
|
12.4
|
Help, my program's too slow! |
12.5
|
Can I stop my application being pirated? |
The exact process for shipping code is very variable, but the steps for
actually producing a release distribution of your software should include the
following
- Get a release build of your code working to the current customer
expectations.
- Determine all dependencies of the code : OS versions, DLLs, OCXs, system
extensions, and ensure that you have legitimately redistributable versions of
all the components which you need to include with your app.
- Build an installation system -using MS, third party or your own
installation apps.
- Verify the installation on multiple configurations, such as clean builds
of the supported operating systems.
- Verify the uninstallation also works reliably. On a clean build it should
delete shared DLLs no longer in use -and on a dirty platform it should leave
them alone.
The first point of contact an end user has with your
product is the installation application: it is critical to invest effort early
on making installation seamless for end users and corporate IT departments.
Start working on it long before the product is ready to ship.
[Top
of Section] [Index]
This
can be quite a hard process. It is inevitable that you will need the C run time
and C++ class libraries for your app -or the Visual Basic or Delphi equivalents.
You must not rely on the destination platforms having any -or up to date-
copies. You will also need any application specific libraries, such as a
database run time, common controls, Borland custom controls or OCXs used.
The "Quick View" operation to view an EXE, DLL, or OCX will give you a list
of which DLLs a program implicitly imports -and viewing these imports will let
you build up a total list of hard coded imports. What can not be determined is
which dynamically loaded libraries are required -such as libraries COM objects.
A bit of intuition and testing is important here. Noting what libraries the
debugger lists as being loaded is the best starting point.
If you have the platform SDK installed, then you can use the excellent
"DEPENDS" utility to offload the hard work of recursively determining which
libraries an EXE or DLL depends upon. It also lists the exact imports and DLL
version information, which is very convenient.
Important: It is the DLL requirements of the release build which you
must determine, not the debug version. You are not allowed to redistribute the
debug versions of the MFC library, even if you wanted to.
Another potential gotcha is the fact that there can be different DLL versions
for different platforms: CTL3D32.DLL is a case in point. Application
distributions must include both versions of such libraries and install the
appropriate one. The VB5 setup wizard gets this wrong
One trouble spot is that some libraries can not be distributed singly
-wininet.dll for example -you have to provvvvide something like a full
redistribution of Internet Explorer to get these to work on 'legacy' platforms.
This bloats your redistribution by tens of megabytes, and forces a system reboot
during the install process, neither of which endear you to end users.
Tip: Any DLL with "OleSelfRegister" in the version fields needs to be
loaded and registered via an invocation of its DllRegisterServer() function -REGSVR32.EXE will do this, as
will many installation packages.
[Top
of Section] [Index]
This can be a common problem, with multiple causes.
- Debug builds automatically zero memory when allocated -this catches some
variable initialisation problems (null pointers) but hides others.
Test:
change the memory allocator, or use Bounds Checker, Purify or an equivalent
tool.
Fix: explicitly initialise all variables
- Debug builds sometimes contain extra padding between variables -or extra
variables, which hide overruns.
Test: use Bounds Checker, Purify or an
equivalent tool.
Fix: don’t overrun arrays, especially string arrays. For
strings, strncpy() beats strcpy() for safe copies, but note that the length
bound version does not zero the last character on an overflow.
- Functions in ASSERT() statements aren't being called.
Test: redefine
ASSERT() as an empty macro in the debug build and see if it breaks.
Fix:
Take all functions with side effects out of assert statements -use the
assertions to verify the results afterwards. Or use the VERIFY() macro, if
present.
- The program contains other side effecting code only included with _DEBUG
is defined
Test: define _DEBUG in the release build and see if it works
-or undefine it in the debug build.
Fix: Take all functions with side
effects out of assert statements -use the assertions to verify the results
afterwards. Or use the VERIFY() macro, if present.
- The optimising code generator is generating broken code.
A problem
which can occasionally arise, especially with an x.0 version of a compiler.
Test:turn off all optimisations in the release build and see if it goes
away. If it does, then try different switches on different modules until the
problem can be located.
Fix: It's often possible by breaking up complex
statements, else disable that optimisation for the offending module.
The best way to avoid these problems is to regularly produce and test
the release build throughout the development process. The release build should
exhibit the exact same defects as the debug build, just at a faster rate.
[Top
of Section] [Index]
Code optimisation
tricks are now covered in more detail in a very long
article
If you discover you have performance when your program is about to ship, then
you are in trouble, as it may be too late to fix in revision 1.0. An action plan
such as the following is probably appropriate.
- Identify potential locations for optimisation, and estimate potential
savings and effort required.
- Get management/customers to agree to the expected slippage -or to accept
the current version as an initial release, with the performance tuned version
as a x.1 upgrade.
Ideally you should have enough of an idea of
performance and load requirements early on in the development process that you
can begin to stress test core components before the product is complete.
"Inadequate Performance" should be just another risk to be managed.
Ways to make windows programs faster:-
- Traditional optimisation techniques
- A good source here is the book "Inner Loops" which
provides details on optimising assembler and C code for the Intel x86
processor family. A useful, but it really needs a counterpart covering the
fast and slow bits of Win32.
- Application code size and layout optimisation
- Tuning your application for size may not seem to have immediate speed
benefits, but an overall shrink and tuning of the app's memory requirements
can reduce the working set of the app and so minimise the chance that needed
routines are off on disk. WSTUNE in the Win32 SDK is useful here.
- Optimise for cache access
- A Pentium system will have 8-16 KB of level 1 code cache, and an
equivalent amount of data cache. (Pentium classic: 8 KB, Pentium MMX: 16 KB),
plus -probably- 256 KB of level 2 cache. These caches speed up memory access
-provided your code makes effective use of them by referring to sequential and
nearby memory locations. So walk through arrays in the order they are stored
in memory, and lay out classes and data structures so that member items often
used together are adjacent. Another good trick is to prefetch 32-byte cache
lines by fetching a DWORD of data from each line in advance of looking at the
contents.
- Align data structures
- The performance penalty of a misaligned data access is frightening. Either
implicitly align data with compiler pack options, or add padding bytes to
explicitly align WORDS, DWORDS and QWORDS on the appropriate boundaries.
- Minimise mispredicted branches
- Pentium class processors use branch prediction to guess the likely path of
code: remembering the taken/not taken status of a number of branches, and
having rules about the likely direction of other branches -usually "backwards
branches taken, forward branches not taken". A mispredicted branch on a
Pentium requires the instruction pipeline to be flushed and restarted, wasting
a few cycles. On a Pentium Pro/PII or other CPU which "speculatively" executes
instructions, the results of all speculated instructions have to be thrown
away if a branch is mispredicted: an even more expensive process.
Branch
misprediction can be minimised by reducing the number of tests in your code
and having easily guessed outcomes: backward branches (for, do {} while)
should normally be taken, and forward branches (if()) not. So put the most
likely outcome of a test in the "then" clause and not the "else" clause. Code
written for the P6/PII only can also use the CMOV instruction to conditionally
move data without having any branches at all, though you need a modern
assembler to generate this opcode.
- Multithread for improved throughput
- This is the only effective way to benefit from the extra processors on a
multi-CPU system. On a single CPU system, the threads can still provide a
throughput boost enable productive work to be done while some of the threads
are busy.
Critical Sections are the lowest penalty synchronization
mechanism (about 17 cycles on '9x if a thread is not blocked) and the
InterlockedXXX functions perfect for manipulating shared data when a critical
section is not required. Aligned WORD, DWORD and QWORD reads and writes are
always atomic, although on a Pentium Pro/II they can take place in a different
order than that the program expects. NB: when data is written to memory in one
CPU, the cache line containing the data will be invalidated in any other CPUs
in the system. Separate shared readable and shared writeable data into
different 32 byte cache lines to minimize the effect of this.
- Make the app more responsive
- For an interactive application, responsiveness can be more important than
actual performance. Splitting the user interaction thread from the worker
threads can create a very responsive application, which is better to use than
a slow single threaded application. A underused technique here is to
"speculate": if you have spare CPU time why not do some background work on the
likelihood it will be needed later. [don't try this on laptops, please]
- Use the overlapped/asynchronous IO operations in NT
- These can be used to stop threads blocking when slow disk or network
operations are taking place. Win95 only implements asynchronous IO on sockets
and serial ports, so this is mostly an NT performance trick.
- Use MMX
- The MMX extensions to x86 enable your program to perform high performance
integer SIMD operations, at the expense of disabling the floating point unit.
As the installed base of MMX CPUs increases (especially in the home market),
the likelihood of customers benefiting from an optional MMX code module is
increasing.
- Offload work to the OS
- The platform and extensions such as DirectX can often deliver high
performance to your application, provided they are used to the full. Spending
some time to discover the most effective approach -as opposed to the most
obvious- is worthwhile. For example, using memory mapped files can reduce
application startup times as there is no need to read in a file byte by byte:
the OS's pager fetches blocks on demand instead.
Turning a single
threaded program into a multithreaded application is not trivial -and you do
need to stress test it on a 2-way, 4-way or greater system to ensure that it
really is immune from deadlocks and race conditions. Such bugs can be
exceedingly troublesome to track down. They are therefore not a last minute
solution to any performance problem. Program Profiling, algorithm tuning, and
optimization for three memory levels are more appropriate at this point in
development.
Corollary: it is often a waste of time getting a high performance algorithm
to work early on in the development process, as the tuned algorithm may be
exceedingly inflexible, and may not even turn out be the bottleneck. It also
creates another major problem: if you replace a fast but flaky beta with a slow
but reliable build, customers often complain about speed. Keeping speed down
until all the bugs have been ironed out avoids you having to worry so much about
the negative performance impact of a bug fix.
[Top
of Section] [Index]
Not in
software, no. You can make it very hard for anyone trying to crack whatever
protection scheme you use, in the hope this will discourage all but the most
dedicated. Serial number checking schemes, expiry coded apps, 'dongle' based
designs -all are ultimately defeatable. One possible exception: smart card
hardware which actually executes an algorithm internally - an algorithm whose
correct functioning is actually vital to the operation of the app (eg. it
contains an encryption routine, or some other important computation function).
If you were sure of a permanent Internet connection and had a 100% uptime server
then maybe you could offload that computation to the server (and have many dial
up and notebook users abandon your product). But even with such tricks, someone
can still reimplement your algorithm in software and patch it into the app. What
does not work is hard coding software to a PC via the hard disk number, the
network address or a PIII serial number; MAC addresses can change easily, and
even CPUs get upgraded -no hardware change should break apps.
Link: a site covering the theory
and practise of cracking apps
[Top
of Section] [Index]
This section contains miscellaneous items
13.1
|
Internet Resources |
13.2
|
Miscellaneous Terminology |
13.3
|
Credits |
13.4
|
Copyright |
This is a list of some web
sites which are a good source of Win32 programming information. Maintaning such
a list is a time consuming exercise in its own right, which is why it is so
brief. Some of the places referenced are good jumping off points to other sites.
- Index of Windows FAQs
- Anyone programming MFC should read and understand Scot Wingo's definitive
MFC FAQ
- The Microsoft software developer
pages and the hardware
equivalents are worth regular visits.
- Intel have developer pages which
can be a source of low level information -ideal for extracting maximum
performance from systems.
- #C++ IRC A good index of lots
of c++ resources
- Programmer magazines: Dr Dobbs Journal,
Microsoft Systems Journal and Windows Developer Journal
- NT/Sys Internals A great site
for reverse engineering NT and '9x, plus the infamous "Blue Screen" screen
saver.
- The MFC code guru site. This is a
very professional site full of MFC code snippets, and with win32 and ATL stuff
too. Visit it before you reinvent an MFC wheel.
- Finally Robert Mashlan's web site is a
good source of URLs, but doesn’t seem to have been updated recently, so its
value is rapidly diminishing.
[Top
of Section] [Index]
Cairo, NT5 Windows 2000 Professional
Chicago, Win95 Windows 95
Checked Build A debug build of a an OS which verifies all arguments
and contains lots of assertions to verify its internal state. Invaluable for
device driver and some program development.
Free Build The faster but less forgiving OS version shipped to paying
customers.
Gold A development term -the 'Gold build' is the one sent to the
manufacturers and customers. Often used to describe OS versions- Win95 gold
versus Win95 OSR2 (that's OEM Service Release 2)
Handle In Win32, a HANDLE is an opaque number which is usually used to
look up a table within part of the OS, and so index OS side data structures. GDI
handles are things like pens, brushes, device contexts and bitmaps, USER handles
are windows and controls, while Kernel Handles can refer to lots of low level
handles. The NT handle model is somewhat more coherent than the other handles
-these are the only handles that you can ppppass in to WaitForSingleObject() and
related functions. Usually only User handles (window handles) can be passed
around to other applications without any effort.
Kernel Mode The state of the CPU in which software is 'privileged',
can read or write any valid memory locations and do things otherwise forbidden,
such as talk to hardware. A bug here leads to a Blue Screen. Commonly called
'Ring 0'.
Memphis, Win98 Windows 98
NT, WinNT Windows NT, and nothing to do with Northern Telecom
Thunk Small piece of code to indirectly link two otherwise
incompatible programs. Used to link 16 and 32 bit applications, and to bind a
windows callback or message proc to a non static C++ member function.
User Mode The underprivileged CPU state, the one applications execute
in. Application crashes here often leave the system standing, especially on NT.
Also known as Ring 3 from the x86 privilege model.
VxD Virtual Device Driver. Very powerful (but low level) device
drivers, the foundation of Windows 9x.
Win16 The generic term for the 16 bit windows API used in Windows
versions 1.0 to 3.1 and still supported in later versions.
Win2K/Windows 2000 NT5, rebadged by marketing weasels.
Win32 The generic term for the 32 bit windows API
Win32s An early implementation Win32 on top of Windows 3.1. A miracle
of technology, hated by all who had to program it as a half way house between
Win16 and Win32
Win9x A term to mean either Windows 95 or 98.
Windoze This is rather derogatory term used to describe Microsoft
Windows. Use of this term in questions offends many professional programmers,
and doesn't garner respect. Only if you are a really good Windows guru canyou
get away with it, and even then it has be semi affectionate.
[Top
of Section] [Index]
Credit for answering many of these
questions must go to the following gurus: Their email addresses aren't listed
here to stop them being sent unsolicited questions. Chris Marriott, Mike Geary,
Bernie Greenberg, John Grant, Robert Mashlan, Matt Arnold, Niels Jacobsen,
Raymond Chen, Paul Dixon, Michael Schubart +many others.
[Top
of Section] [Index]
This FAQ is copyright 1996-1999 Steve Loughran. You can keep and print
out copies for your own use, provided this copyright notice is retained, and you
can also store it for the benefit of your colleagues/team members/fellow
students/whatever on your local intranet web server. You may not redistribute it
for profit, in printed or on line form. Any included code samples in the
document are yours to reuse as you wish, without any copyright restrictions at
all.
If you keep an on line copy of ths FAQ, please retain a pointer to the
original document at http://www.iseran.com/Win32/FAQ/.
This is the only way to stop getting email complaints about the document being
wildly out of date, when it's really that the reader just needs to see a recent
copy.
The author can be contacted at faq-contact99 at iseran.com.
Corrections, additions and constructive criticism are welcomed. Programming
questions are -sadly- not and are likely to be ignored. I would like to help but
I have too many outstanding tasks from my paid work to act as an unpaid
consultant to the rest of the world. Please read and understand the FAQ then
post to the newsgroups instead.
Disclaimer This document contains code samples and "tips" intended to
help you write better Windows programs. Use all of them at their own risk. It is
not my problem if you use the information in here in a flight control system on
a passenger jet which then falls out of the sky. OK?
Finally, I hope you found this useful. Enjoy your programming and don't let
impossible deadlines or broken applications get you down -they are part of every
Win32 programmer's life!
-Steve.
[Top of Section] [Index]